diff options
477 files changed, 19152 insertions, 8843 deletions
diff --git a/core/array.cpp b/core/array.cpp index d65bddae61..cd4e0fb4c8 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -30,8 +30,10 @@ #include "array.h" +#include "container_type_validate.h" #include "core/hashfuncs.h" #include "core/object.h" +#include "core/script_language.h" #include "core/variant.h" #include "core/vector.h" @@ -39,6 +41,8 @@ class ArrayPrivate { public: SafeRefCount refcount; Vector<Variant> array; + + ContainerTypeValidate typed; }; void Array::_ref(const Array &p_from) const { @@ -108,12 +112,59 @@ uint32_t Array::hash() const { } return h; } -void Array::operator=(const Array &p_array) { - _ref(p_array); +void Array::_assign(const Array &p_array) { + + if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) { + //same type or untyped, just reference, shuold be fine + _ref(p_array); + } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway + _p->array = p_array._p->array; + } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid + if (_p->typed.type == Variant::OBJECT) { + //for objects, it needs full validation, either can be converted or fail + for (int i = 0; i < p_array._p->array.size(); i++) { + if (!_p->typed.validate(p_array._p->array[i], "assign")) { + return; + } + } + _p->array = p_array._p->array; //then just copy, which is cheap anyway + + } else { + //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case. + Vector<Variant> new_array; + new_array.resize(p_array._p->array.size()); + for (int i = 0; i < p_array._p->array.size(); i++) { + Variant src_val = p_array._p->array[i]; + if (src_val.get_type() == _p->typed.type) { + new_array.write[i] = src_val; + } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) { + Variant *ptr = &src_val; + Callable::CallError ce; + new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } else { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } + + _p->array = new_array; + } + } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible + _ref(p_array); + } else { + ERR_FAIL_MSG("Assignment of arrays of incompatible types."); + } +} + +void Array::operator=(const Array &p_array) { + _assign(p_array); } void Array::push_back(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back")); _p->array.push_back(p_value); } @@ -124,11 +175,13 @@ Error Array::resize(int p_new_size) { void Array::insert(int p_pos, const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "insert")); _p->array.insert(p_pos, p_value); } void Array::erase(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "erase")); _p->array.erase(p_value); } @@ -144,6 +197,7 @@ Variant Array::back() const { int Array::find(const Variant &p_value, int p_from) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1); return _p->array.find(p_value, p_from); } @@ -151,6 +205,7 @@ int Array::rfind(const Variant &p_value, int p_from) const { if (_p->array.size() == 0) return -1; + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1); if (p_from < 0) { // Relative offset from the end @@ -173,11 +228,13 @@ int Array::rfind(const Variant &p_value, int p_from) const { int Array::find_last(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1); return rfind(p_value); } int Array::count(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0); if (_p->array.size() == 0) return 0; @@ -193,6 +250,8 @@ int Array::count(const Variant &p_value) const { } bool Array::has(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false); + return _p->array.find(p_value, 0) != -1; } @@ -203,6 +262,8 @@ void Array::remove(int p_pos) { void Array::set(int p_idx, const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "set")); + operator[](p_idx) = p_value; } @@ -216,6 +277,7 @@ Array Array::duplicate(bool p_deep) const { Array new_arr; int element_count = size(); new_arr.resize(element_count); + new_arr._p->typed = _p->typed; for (int i = 0; i < element_count; i++) { new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i); } @@ -369,11 +431,13 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value int Array::bsearch(const Variant &p_value, bool p_before) { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1); return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); } int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); ERR_FAIL_NULL_V(p_obj, 0); _ArrayVariantSortCustom less; @@ -391,6 +455,7 @@ Array &Array::invert() { void Array::push_front(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front")); _p->array.insert(0, p_value); } @@ -465,6 +530,27 @@ const void *Array::id() const { return _p->array.ptr(); } +Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { + _p = memnew(ArrayPrivate); + _p->refcount.init(); + set_typed(p_type, p_class_name, p_script); + _assign(p_from); +} + +void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { + ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty."); + ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user."); + ERR_FAIL_COND_MSG(_p->typed.type != Variant::NIL, "Type can only be set once."); + ERR_FAIL_COND_MSG(p_class_name != StringName() && p_type != Variant::OBJECT, "Class names can only be set for type OBJECT"); + Ref<Script> script = p_script; + ERR_FAIL_COND_MSG(script.is_valid() && p_class_name == StringName(), "Script class can only be set together with base class name"); + + _p->typed.type = Variant::Type(p_type); + _p->typed.class_name = p_class_name; + _p->typed.script = script; + _p->typed.where = "TypedArray"; +} + Array::Array(const Array &p_from) { _p = nullptr; diff --git a/core/array.h b/core/array.h index 3b14bdb9fe..2840ce199c 100644 --- a/core/array.h +++ b/core/array.h @@ -47,6 +47,10 @@ class Array { int _clamp_index(int p_index) const; static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod); +protected: + Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); + void _assign(const Array &p_array); + public: Variant &operator[](int p_idx); const Variant &operator[](int p_idx) const; @@ -101,6 +105,7 @@ public: const void *id() const; + void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script); Array(const Array &p_from); Array(); ~Array(); diff --git a/core/container_type_validate.h b/core/container_type_validate.h new file mode 100644 index 0000000000..3721668033 --- /dev/null +++ b/core/container_type_validate.h @@ -0,0 +1,98 @@ +#ifndef CONTAINER_TYPE_VALIDATE_H +#define CONTAINER_TYPE_VALIDATE_H + +#include "core/script_language.h" +#include "core/variant.h" + +struct ContainerTypeValidate { + + Variant::Type type = Variant::NIL; + StringName class_name; + Ref<Script> script; + const char *where = "conatiner"; + + _FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const { + if (type == p_type.type) { + if (type != Variant::OBJECT) { + return true; //nothing else to check + } + } else { + return false; + } + + //both are object + + if ((class_name != StringName()) != (p_type.class_name != StringName())) { + return false; //both need to have class or none + } + + if (class_name != p_type.class_name) { + if (!ClassDB::is_parent_class(p_type.class_name, class_name)) { + return false; + } + } + + if (script.is_null() != p_type.script.is_null()) { + return false; + } + + if (script != p_type.script) { + if (!p_type.script->inherits_script(script)) { + return false; + } + } + + return true; + } + + _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") { + + if (type == Variant::NIL) { + return true; + } + + ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); + if (type != p_variant.get_type()) { + return false; + } + + if (type != Variant::OBJECT) { + return true; + } +#ifdef DEBUG_ENABLED + ObjectID object_id = p_variant; + if (object_id == ObjectID()) { + return true; //fine its null; + } + Object *object = ObjectDB::get_instance(object_id); + ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); +#else + Object *object = p_variant; + if (object == nullptr) { + return true; //fine + } +#endif + if (class_name == StringName()) { + return true; //all good, no class type requested + } + + StringName obj_class = object->get_class_name(); + if (obj_class != class_name) { + ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'."); + } + + if (script.is_null()) { + return true; //all good + } + + Ref<Script> other_script = object->get_script(); + + //check base script.. + ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + + return true; + } +}; + +#endif // CONTAINER_TYPE_VALIDATE_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index ab8548e3ba..233f62bd15 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -99,7 +99,7 @@ Crypto::Crypto() { /// Resource loader/saver -RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { String el = p_path.get_extension().to_lower(); if (el == "crt") { diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index e515367de5..d9becab958 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -84,18 +84,14 @@ public: }; class ResourceFormatLoaderCrypto : public ResourceFormatLoader { - GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader); - public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; }; class ResourceFormatSaverCrypto : public ResourceFormatSaver { - GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver); - public: virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index e6bcc5f77e..fd109c62b6 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -33,7 +33,7 @@ #include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "core/script_language.h" @@ -659,9 +659,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug. - InputFilter::MouseMode mouse_mode = InputFilter::get_singleton()->get_mouse_mode(); - if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE) - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode(); + if (mouse_mode != Input::MOUSE_MODE_VISIBLE) + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); uint64_t loop_begin_usec = 0; uint64_t loop_time_sec = 0; @@ -779,8 +779,8 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { send_message("debug_exit", Array()); - if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE) - InputFilter::get_singleton()->set_mouse_mode(mouse_mode); + if (mouse_mode != Input::MOUSE_MODE_VISIBLE) + Input::get_singleton()->set_mouse_mode(mouse_mode); } void RemoteDebugger::poll_events(bool p_is_idle) { diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 6f6b8c1dd3..afcb283e05 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -568,6 +568,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY); + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE); diff --git a/core/image.cpp b/core/image.cpp index 2097f27b01..58351ae2e5 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -879,6 +879,9 @@ void Image::resize_to_po2(bool p_square) { int w = next_power_of_2(width); int h = next_power_of_2(height); + if (p_square) { + w = h = MAX(w, h); + } if (w == width && h == height) { diff --git a/core/input/SCsub b/core/input/SCsub index d46e52a347..c641819698 100644 --- a/core/input/SCsub +++ b/core/input/SCsub @@ -8,8 +8,6 @@ import input_builders # Order matters here. Higher index controller database files write on top of lower index database files. controller_databases = [ - "#core/input/gamecontrollerdb_204.txt", - "#core/input/gamecontrollerdb_205.txt", "#core/input/gamecontrollerdb.txt", "#core/input/godotcontrollerdb.txt", ] diff --git a/core/input/gamecontrollerdb_204.txt b/core/input/gamecontrollerdb_204.txt deleted file mode 100644 index 7fbe925b25..0000000000 --- a/core/input/gamecontrollerdb_204.txt +++ /dev/null @@ -1,269 +0,0 @@ -# Game Controller DB for SDL in 2.0.4 format -# Source: https://github.com/gabomdq/SDL_GameControllerDB - -# Windows -02200090000000000000504944564944,8Bitdo NES30 PRO USB,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, -8f0e1200000000000000504944564944,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, -341a3608000000000000504944564944,Afterglow 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, -c0111352000000000000504944564944,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, -d81d0b00000000000000504944564944,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, -e8206058000000000000504944564944,Cideko AK08b,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:Windows, -5e048e02000000000000504944564944,Controller (XBOX 360 For Windows),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,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, -791d0103000000000000504944564944,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows, -4f0423b3000000000000504944564944,Dual Trigger 3-in-1,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, -341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -0d0f8500000000000000504944564944,Fighting Commander 2016 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:Windows, -0d0f5e00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -0d0f5f00000000000000504944564944,Fighting Commander 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:a3,start:b9,x:b0,y:b3,platform:Windows, -0d0f8400000000000000504944564944,Fighting Commander 5,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:Windows, -0d0f8700000000000000504944564944,Fighting Stick 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, -0d0f8800000000000000504944564944,Fighting Stick 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, -0d0f2700000000000000504944564944,FIGHTING STICK 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, -79000600000000000000504944564944,G-Shark GS-GP702,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:a4,start:b9,x:b3,y:b0,platform:Windows, -28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -ffff0000000000000000504944564944,GameStop Gamepad,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:Windows, -6d0416c2000000000000504944564944,Generic DirectInput 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, -45130010000000000000504944564944,Generic USB Joystick,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:Windows, -0d0f4900000000000000504944564944,Hatsune Miku Sho 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, -d8140862000000000000504944564944,HitBox Edition Cthulhu+,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, -0d0f4000000000000000504944564944,Hori Fighting Stick 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, -0d0f6e00000000000000504944564944,HORIPAD 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:a3,start:b9,x:b0,y:b3,platform:Windows, -0d0fee00000000000000504944564944,HORIPAD mini4,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:Windows, -0d0f4d00000000000000504944564944,HORIPAD3 A,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, -25090017000000000000504944564944,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, -d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,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:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,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:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows, -6f0e2401000000000000504944564944,INJUSTICE FightStick for PS3,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, -49190204000000000000504944564944,Ipega PG-9023,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -6d0418c2000000000000504944564944,Logitech F510 Gamepad,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, -6d0419c2000000000000504944564944,Logitech F710 Gamepad,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, -38075032000000000000504944564944,Mad Catz FightPad PRO 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:Windows, -38075082000000000000504944564944,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,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, -38078433000000000000504944564944,Mad Catz FightStick TE S+ PS3,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, -38078483000000000000504944564944,Mad Catz FightStick TE S+ 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,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -38078134000000000000504944564944,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -38078184000000000000504944564944,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -38078034000000000000504944564944,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -38078084000000000000504944564944,Mad Catz TE2 PS4 Fightstick,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:Windows, -38078532000000000000504944564944,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -38073888000000000000504944564944,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -38071888000000000000504944564944,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha 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,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -25090128000000000000504944564944,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, -79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, -8f0e1030000000000000504944564944,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, -2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, -79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),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, -8f0e0d31000000000000504944564944,Multilaser JS071 USB,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, -100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -bd1215d0000000000000504944564944,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, -4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows, -36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows, -4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows, -120cf60e000000000000504944564944,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, -8f0e0300000000000000504944564944,Piranha xtreme,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, -d6206dca000000000000504944564944,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, -10080100000000000000504944564944,PS1 USB,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, -10080300000000000000504944564944,PS2 USB,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:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, -4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, -88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, -25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, -10008200000000000000504944564944,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -4c05c405000000000000504944564944,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -300f0011000000000000504944564944,QanBa Arcade JoyStick 1008,a:b1,b:b2,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,start:b10,x:b0,y:b3,platform:Windows, -300f1611000000000000504944564944,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, -222c0020000000000000504944564944,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, -300f1210000000000000504944564944,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, -341a0104000000000000504944564944,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, -222c0223000000000000504944564944,Qanba Obsidian Arcade Joystick PS3 Mode,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, -222c0023000000000000504944564944,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,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, -0d0f1100000000000000504944564944,REAL ARCADE PRO.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,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -0d0f6a00000000000000504944564944,Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -0d0f6b00000000000000504944564944,Real Arcade Pro.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:a3,start:b9,x:b0,y:b3,platform:Windows, -0d0f8a00000000000000504944564944,Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -0d0f8b00000000000000504944564944,Real Arcade Pro.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:a3,start:b9,x:b0,y:b3,platform:Windows, -0d0f7000000000000000504944564944,REAL ARCADE PRO.4 VLX,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:Windows, -0d0f2200000000000000504944564944,REAL ARCADE Pro.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,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, -00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, -6f0e1e01000000000000504944564944,Rock Candy Gamepad for 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:Windows, -300f1201000000000000504944564944,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows, -300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -9b280500000000000000504944564944,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, -79001100000000000000504944564944,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows, -4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,back:b13,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, -4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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, -ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,back:b4,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:a4,start:b5,x:b0,y:b1,platform:Windows, -4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, -4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, -66660488000000000000504944564944,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, -38076652000000000000504944564944,UnKnown,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, -63252305000000000000504944564944,USB Vibration Joystick (BM),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:Windows, -79001b18000000000000504944564944,Venom Arcade Joystick,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, -xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, - -# Mac OS X -10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -830500000000000031b0000000000000,Cideko AK08b,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:Mac OS X, -79000000000000000600000000000000,G-Shark GP-702,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X, -AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,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, -0500000047532047616d657061640000,GameStop Gamepad,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:Mac OS X, -0d0f0000000000004d00000000000000,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, -0d0f0000000000006600000000000000,HORIPAD FPS PLUS 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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, -83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, -6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),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:Mac OS X, -6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),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:Mac OS X, -6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),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, -6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),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:Mac OS X, -2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, -79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, -d814000000000000cecf000000000000,MC Cthulhu,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, -8f0e0000000000000300000000000000,Piranha xtreme,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:Mac OS X, -4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, -4c05000000000000c405000000000000,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: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, -891600000000000000fd000000000000,Razer Onza Tournament,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, -79000000000000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, -81170000000000007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, -b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, -351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,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, -4c05000000000000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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, -11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, -11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, -4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X, -4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X, -bd1200000000000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, -10080000000000000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, -050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, -050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, -5e040000000000008e02000000000000,X360 Controller,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, -5e04000000000000dd02000000000000,Xbox One Wired Controller,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, -5e04000000000000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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:Mac OS X, -5e04000000000000ea02000000000000,Xbox Wireless Controller,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, - -# Linux -05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, -05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, -030000006f0e00003901000020060000,Afterglow Wired Controller for 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, -03000000e82000006058000001010000,Cideko AK08b,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:Linux, -03000000790000000600000010010000,DragonRise Inc. Generic USB 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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e00003001000001010000,EA Sports 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, -03000000341a000005f7000010010000,GameCube {HuiJia USB box},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, -03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,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:b1,y:b3,platform:Linux, -0500000047532047616d657061640000,GameStop Gamepad,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, -030000006f0e00000104000000010000,Gamestop Logic3 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, -030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006f0e00001f01000000010000,Generic X-Box pad,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, -03000000f0250000c183000010010000,Goodbetterbest Ltd USB 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, -03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, -030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,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:Linux, -030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, -03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,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:Linux, -06000000adde0000efbe000002010000,Hidromancer Game 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, -03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, -03000000c9110000f055000011010000,HJC Game GAMEPAD,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, -030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, -030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 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, -030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.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: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, -03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, -03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, -030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, -03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, -03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e00000103000000020000,Logic3 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, -030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,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, -030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),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, -030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),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, -030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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, -030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),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, -030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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, -030000006d04000016c2000010010000,Logitech Logitech Dual Action,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, -030000006d04000018c2000010010000,Logitech RumblePad 2,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, -030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, -05000000380700006652000025010000,Mad Catz C.T.R.L.R ,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, -03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, -03000000380700001647000010040000,Mad Catz Wired Xbox 360 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, -03000000ad1b000016f0000090040000,Mad Catz Xbox 360 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, -03000000780000000600000010010000,Microntek USB Joystick,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, -030000005e0400008e02000004010000,Microsoft X-Box 360 pad,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, -030000005e0400008e02000062230000,Microsoft X-Box 360 pad,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, -030000005e040000dd02000003020000,Microsoft X-Box One pad v2,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, -030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, -030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, -05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, -030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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, -05000000010000000100000003000000,Nintendo Wiimote,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, -03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000451300000830000010010000,NYKO CORE,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, -05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, -05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, -03000000ff1100003133000010010000,PC Game Controller,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: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, -030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -030000004c050000c405000011010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -050000004c050000c405000000010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, -030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -03000000c6240000045d000025010000,Razer Sabertooth,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, -03000000321500000009000011010000,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:Linux, -050000003215000000090000163a0000,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:Linux, -03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, -0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, -0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, -030000006f0e00001e01000011010000,Rock Candy Gamepad for 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, -030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,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, -03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,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:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, -03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, -03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, -030000004c050000c405000011810000,Sony DualShock 4,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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,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:Linux, -050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,back:b13,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:Linux, -030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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:Linux, -03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,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:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, -030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,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, -030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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, -03000000de280000fc11000001000000,Steam 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, -03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, -030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, -030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, -030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,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:Linux, -030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, -030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,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:Linux, -030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless 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, -03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, -03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, -03000000100800000100000010010000,Twin USB PS2 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:Linux, -03000000100800000300000010010000,USB Gamepad,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:Linux, -03000000de280000ff11000001000000,Valve Streaming Gamepad,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, -05000000ac0500003232000001000000,VR-BOX,a:b0,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:b2,y:b3,platform:Linux, -030000005e0400008e02000010010000,X360 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, -030000005e0400008e02000014010000,X360 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, -030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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:Linux, -030000005e040000d102000001010000,Xbox One Wireless 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, -050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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:Linux, -03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, -xinput,XInput 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, - -# Android -4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,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, - -# 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, diff --git a/core/input/gamecontrollerdb_205.txt b/core/input/gamecontrollerdb_205.txt deleted file mode 100644 index 55c45eb148..0000000000 --- a/core/input/gamecontrollerdb_205.txt +++ /dev/null @@ -1,337 +0,0 @@ -# Game Controller DB for SDL in 2.0.5 format -# Source: https://github.com/gabomdq/SDL_GameControllerDB - -# Windows -03000000022000000090000000000000,8Bitdo NES30 PRO USB,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -03000000203800000900000000000000,8Bitdo NES30 PRO Wireless,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, -10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, -030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, -03000000341a00003608000000000000,Afterglow 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, -341a3608000000000000504944564944,Afterglow 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, -03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, -030000006b1400000055000000000000,bigben ps3padstreetnew,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:Windows, -0300000066f700000500000000000000,BrutalLegendTest,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:a3,righty:a2,start:b9,x:b0,y:b3,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, -e8206058000000000000504944564944,Cideko AK08b,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:Windows, -030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),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,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, -030000004f04000023b3000000000000,Dual Trigger 3-in-1,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, -03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -030000000d0f00008500000000000000,Fighting Commander 2016 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:Windows, -030000000d0f00005e00000000000000,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00005f00000000000000,Fighting Commander 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:a3,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00008400000000000000,Fighting Commander 5,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:Windows, -030000000d0f00008700000000000000,Fighting Stick 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,Fighting Stick 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, -030000000d0f00002700000000000000,FIGHTING STICK 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, -78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows, -03000000790000000600000000000000,G-Shark GS-GP702,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:a4,start:b9,x:b3,y:b0,platform:Windows, -03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, -030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,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, -03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -03000000ffff00000000000000000000,GameStop Gamepad,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:Windows, -ffff0000000000000000504944564944,GameStop Gamepad,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:Windows, -030000006d04000016c2000000000000,Generic DirectInput 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, -6d0416c2000000000000504944564944,Generic DirectInput 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, -03000000451300000010000000000000,Generic USB Joystick,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:Windows, -03000000341a00000302000000000000,Hama Scorpad,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, -030000000d0f00004900000000000000,Hatsune Miku Sho 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, -03000000d81400000862000000000000,HitBox Edition Cthulhu+,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, -030000000d0f00004000000000000000,Hori Fighting Stick 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, -030000000d0f00006e00000000000000,HORIPAD 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:a3,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00004d00000000000000,HORIPAD3 A,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, -03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, -03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,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:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,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:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows, -03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,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, -03000000491900000204000000000000,Ipega PG-9023,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -030000006d04000019c2000000000000,Logitech Cordless RumblePad 2 USB,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, -030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows, -6d0418c2000000000000504944564944,Logitech F510 Gamepad,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, -6d0419c2000000000000504944564944,Logitech F710 Gamepad,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, -030000006d04000018c2000000000000,Logitech RumblePad 2,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, -03000000380700005032000000000000,Mad Catz FightPad PRO 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:Windows, -03000000380700005082000000000000,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,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, -03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,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, -03000000380700008483000000000000,Mad Catz FightStick TE S+ 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,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,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:Windows, -03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha 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,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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:Windows, -03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, -03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, -030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, -0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, -03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),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, -030000001008000001e5000000000000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, -030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows, -03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows, -4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows, -03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, -030000008f0e00000300000000000000,Piranha xtreme,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, -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, -030000008f0e00007530000000000000,PS (R) Gamepad,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:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,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:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, -03000000100800000100000000000000,PS1 USB,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, -03000000100800000300000000000000,PS2 USB,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:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, -03000000888800000803000000000000,PS3,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, -030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, -4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, -88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, -03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, -25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, -03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -030000004c050000c405000000000000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -4c05c405000000000000504944564944,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,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,start:b10,x:b0,y:b3,platform:Windows, -03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, -03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, -03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, -03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, -03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,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, -03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,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, -03000000321500000003000000000000,Razer Hydra,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,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, -030000000d0f00001100000000000000,REAL ARCADE PRO.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,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00006a00000000000000,Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00006b00000000000000,Real Arcade Pro.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:a3,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00008a00000000000000,Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00008b00000000000000,Real Arcade Pro.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:a3,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,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:Windows, -030000000d0f00002200000000000000,REAL ARCADE Pro.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,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -030000000d0f00005b00000000000000,Real Arcade Pro.V4,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:Windows, -030000000d0f00005c00000000000000,Real Arcade Pro.V4,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, -0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, -0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, -030000006f0e00001e01000000000000,Rock Candy Gamepad for 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:Windows, -030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000a30600001af5000000000000,Saitek Cyborg,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, -03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,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:a4,start:b9,x:b0,y:b3,platform:Windows, -03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -03000000a30600000cff000000000000,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows, -03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, -03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -03000000a30600000b04000000000000,Saitek P990,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:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, -03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, -030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, -03000000790000001100000000000000,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows, -03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, -030000004c050000cc09000000000000,Sony DualShock 4,a:b1,b:b2,back:b13,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, -030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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, -030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,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:Windows, -03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,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:a4,start:b5,x:b0,y:b1,platform:Windows, -03000000fa1900000706000000000000,Team 5,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:Windows, -03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, -030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, -030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, -03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, -03000000d90400000200000000000000,TwinShock PS2,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, -03000000380700006652000000000000,UnKnown,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, -03000000632500002305000000000000,USB Vibration Joystick (BM),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:Windows, -03000000790000001b18000000000000,Venom Arcade Joystick,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, -03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, -xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, - -# Mac OS X -03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -10280000000000000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -830500000000000031b0000000000000,Cideko AK08b,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:Mac OS X, -03000000790000000600000000000000,G-Shark GP-702,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X, -03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,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, -0500000047532047616d657061640000,GameStop Gamepad,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:Mac OS X, -030000000d0f00005f00000000000000,HORI Fighting Commander 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,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, -030000000d0f00005e00000000000000,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,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, -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, -030000000d0f00006600000000000000,HORIPAD FPS PLUS 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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, -03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, -030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),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:Mac OS X, -6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),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:Mac OS X, -030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),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:Mac OS X, -6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),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:Mac OS X, -030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),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, -6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),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, -030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),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:Mac OS X, -6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),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:Mac OS X, -0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, -03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, -03000000d8140000cecf000000000000,MC Cthulhu,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, -030000008f0e00000300000000000000,Piranha xtreme,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:Mac OS X, -030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, -4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, -030000004c050000c405000000000000,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: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, -4c05000000000000c405000000000000,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: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, -030000008916000000fd000000000000,Razer Onza TE,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, -03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, -03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, -03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, -030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, -030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,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, -030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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, -11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, -11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, -030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X, -030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X, -03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, -03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, -050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, -050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, -030000005e0400008e02000000000000,X360 Controller,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, -5e040000000000008e02000000000000,X360 Controller,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, -030000005e040000dd02000000000000,Xbox One Wired Controller,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, -030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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:Mac OS X, -030000005e040000ea02000000000000,Xbox Wireless Controller,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, - -# Linux -05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,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, -03000000c82d00000190000011010000,8Bitdo NES30 Pro 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, -05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, -05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, -030000006f0e00003901000020060000,Afterglow Wired Controller for 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, -03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, -03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, -03000000e82000006058000001010000,Cideko AK08b,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:Linux, -03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, -03000000790000000600000010010000,DragonRise Inc. Generic USB 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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e00003001000001010000,EA Sports 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, -03000000341a000005f7000010010000,GameCube {HuiJia USB box},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, -03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,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:b1,y:b3,platform:Linux, -0500000047532047616d657061640000,GameStop Gamepad,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, -030000006f0e00000104000000010000,Gamestop Logic3 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, -030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006f0e00001f01000000010000,Generic X-Box pad,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, -03000000f0250000c183000010010000,Goodbetterbest Ltd USB 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, -03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, -030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,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:Linux, -030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, -03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,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:Linux, -0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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, -06000000adde0000efbe000002010000,Hidromancer Game 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, -03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, -03000000c9110000f055000011010000,HJC Game GAMEPAD,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, -030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, -030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 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, -030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.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: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, -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, -03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, -050000006964726f69643a636f6e0000,idroid:con,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, -03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, -030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, -03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, -03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e00000103000000020000,Logic3 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, -030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,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, -030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),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, -030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),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, -030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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, -030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),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, -030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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, -030000006d04000016c2000010010000,Logitech Logitech Dual Action,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, -030000006d04000018c2000010010000,Logitech RumblePad 2,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, -030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, -05000000380700006652000025010000,Mad Catz C.T.R.L.R ,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, -03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, -03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000380700008084000011010000,Mad Catz fightstick (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:Linux, -03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000380700008483000011010000,Mad Catz FightStick TE S+ 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:Linux, -03000000380700001647000010040000,Mad Catz Wired Xbox 360 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, -03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, -03000000ad1b000016f0000090040000,Mad Catz Xbox 360 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, -03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000780000000600000010010000,Microntek USB Joystick,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, -030000005e0400008e02000004010000,Microsoft X-Box 360 pad,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, -030000005e0400008e02000062230000,Microsoft X-Box 360 pad,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, -030000005e040000dd02000003020000,Microsoft X-Box One pad v2,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, -030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, -030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, -05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, -030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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, -05000000010000000100000003000000,Nintendo Wiimote,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, -03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000451300000830000010010000,NYKO CORE,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, -030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, -05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, -05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, -03000000ff1100003133000010010000,PC Game Controller,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: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, -030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, -030000004c050000c405000011010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -030000004c050000cc09000011010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -050000004c050000c405000000010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -050000004c050000cc09000000010000,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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, -030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, -030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -03000000c6240000045d000025010000,Razer Sabertooth,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, -03000000321500000009000011010000,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:Linux, -050000003215000000090000163a0000,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:Linux, -03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, -0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, -0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, -030000006f0e00001e01000011010000,Rock Candy Gamepad for 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, -030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,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, -03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,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:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, -03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, -03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, -030000004c050000c405000011810000,Sony DualShock 4,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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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:Linux, -030000004c0500006802000011810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -050000004c0500006802000000810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, -03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,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:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, -030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,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, -030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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, -03000000de280000fc11000001000000,Steam 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, -03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, -030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, -030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, -030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,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:Linux, -030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, -030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,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:Linux, -030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless 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, -03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, -03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, -03000000100800000100000010010000,Twin USB PS2 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:Linux, -03000000100800000300000010010000,USB Gamepad,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:Linux, -03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, -03000000de280000ff11000001000000,Valve Streaming Gamepad,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, -05000000ac0500003232000001000000,VR-BOX,a:b0,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:b2,y:b3,platform:Linux, -030000005e0400008e02000010010000,X360 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, -030000005e0400008e02000014010000,X360 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, -030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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, -030000005e040000a102000007010000,X360 Wireless 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, -0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, -0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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:Linux, -030000005e040000d102000001010000,Xbox One Wireless 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, -050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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:Linux, -03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, -xinput,XInput 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, - -# Android -4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,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, - -# 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, diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt index 472b01947b..f6411e2429 100644 --- a/core/input/godotcontrollerdb.txt +++ b/core/input/godotcontrollerdb.txt @@ -1,29 +1,6 @@ -# Game Controller DB for SDL in 2.0.6+ format +# Game Controller DB for Godot in SDL 2.0.10 format # Source: https://github.com/godotengine/godot -# Windows -9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,platform:Windows, -c911f055000000000000504944564944,GAMEPAD,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:Windows, -__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows, - -# Linux -030000006f0e00001302000000010000,Afterglow Gamepad for Xbox 360,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, -05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,platform:Linux, -030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftstick:b9,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,platform:Linux, -03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,platform:Linux, -030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,platform:Linux, -030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux, -030000005e040000ea02000001030000,Xbox One Wireless 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, - -# Android -4f5559412047616d6520436f6e74726f,OUYA Game Controller,leftx:a1,lefty:a3,dpdown:b12,rightstick:b8,rightshoulder:b10,rightx:a6,start:b-86,righty:a7,dpleft:b13,lefttrigger:b15,x:b2,dpup:b11,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:b14,righttrigger:b16,b:b1,platform:Android, -Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android, -532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,platform:Android, -506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Android, -4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android, -484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Android, -47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,platform:Android, - # Javascript Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Javascript, c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript, diff --git a/core/input/input_filter.cpp b/core/input/input.cpp index 2e8442a905..5301f5f4ee 100644 --- a/core/input/input_filter.cpp +++ b/core/input/input.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* input_filter.cpp */ +/* input.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "input_filter.h" +#include "input.h" #include "core/input/default_controller_mappings.h" #include "core/input/input_map.h" @@ -39,71 +39,71 @@ #include "editor/editor_settings.h" #endif -InputFilter *InputFilter::singleton = nullptr; +Input *Input::singleton = nullptr; -void (*InputFilter::set_mouse_mode_func)(InputFilter::MouseMode) = nullptr; -InputFilter::MouseMode (*InputFilter::get_mouse_mode_func)() = nullptr; -void (*InputFilter::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr; -InputFilter::CursorShape (*InputFilter::get_current_cursor_shape_func)() = nullptr; -void (*InputFilter::set_custom_mouse_cursor_func)(const RES &, InputFilter::CursorShape, const Vector2 &) = nullptr; +void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr; +Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr; +void (*Input::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr; +Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr; +void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr; -InputFilter *InputFilter::get_singleton() { +Input *Input::get_singleton() { return singleton; } -void InputFilter::set_mouse_mode(MouseMode p_mode) { +void Input::set_mouse_mode(MouseMode p_mode) { ERR_FAIL_INDEX((int)p_mode, 4); set_mouse_mode_func(p_mode); } -InputFilter::MouseMode InputFilter::get_mouse_mode() const { +Input::MouseMode Input::get_mouse_mode() const { return get_mouse_mode_func(); } -void InputFilter::_bind_methods() { - - ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &InputFilter::is_key_pressed); - ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &InputFilter::is_mouse_button_pressed); - ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &InputFilter::is_joy_button_pressed); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &InputFilter::is_action_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &InputFilter::is_action_just_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &InputFilter::is_action_just_released); - ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputFilter::get_action_strength); - ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &InputFilter::add_joy_mapping, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &InputFilter::remove_joy_mapping); - ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &InputFilter::joy_connection_changed); - ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &InputFilter::is_joy_known); - ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &InputFilter::get_joy_axis); - ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &InputFilter::get_joy_name); - ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &InputFilter::get_joy_guid); - ClassDB::bind_method(D_METHOD("get_connected_joypads"), &InputFilter::get_connected_joypads); - ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &InputFilter::get_joy_vibration_strength); - ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &InputFilter::get_joy_vibration_duration); - ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &InputFilter::get_joy_button_string); - ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &InputFilter::get_joy_button_index_from_string); - ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &InputFilter::get_joy_axis_string); - ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &InputFilter::get_joy_axis_index_from_string); - ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &InputFilter::start_joy_vibration, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &InputFilter::stop_joy_vibration); - ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &InputFilter::vibrate_handheld, DEFVAL(500)); - ClassDB::bind_method(D_METHOD("get_gravity"), &InputFilter::get_gravity); - ClassDB::bind_method(D_METHOD("get_accelerometer"), &InputFilter::get_accelerometer); - ClassDB::bind_method(D_METHOD("get_magnetometer"), &InputFilter::get_magnetometer); - ClassDB::bind_method(D_METHOD("get_gyroscope"), &InputFilter::get_gyroscope); - ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &InputFilter::get_last_mouse_speed); - ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &InputFilter::get_mouse_button_mask); - ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &InputFilter::set_mouse_mode); - ClassDB::bind_method(D_METHOD("get_mouse_mode"), &InputFilter::get_mouse_mode); - ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &InputFilter::warp_mouse_position); - ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &InputFilter::action_press, DEFVAL(1.f)); - ClassDB::bind_method(D_METHOD("action_release", "action"), &InputFilter::action_release); - ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &InputFilter::set_default_cursor_shape, DEFVAL(CURSOR_ARROW)); - ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &InputFilter::get_current_cursor_shape); - ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &InputFilter::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2())); - ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &InputFilter::parse_input_event); - ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &InputFilter::set_use_accumulated_input); +void Input::_bind_methods() { + + ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed); + ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed); + ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed); + ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed); + ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed); + ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released); + ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength); + ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping); + ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed); + ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known); + ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis); + ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name); + ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid); + ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads); + ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength); + ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration); + ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &Input::get_joy_button_string); + ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string); + ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string); + ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string); + ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration); + ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500)); + ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity); + ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer); + ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer); + ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope); + ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed); + ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask); + ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode); + ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode); + ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position); + ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f)); + ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release); + ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW)); + ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &Input::get_current_cursor_shape); + ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2())); + ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event); + ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input); BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE); BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); @@ -131,7 +131,7 @@ void InputFilter::_bind_methods() { ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected"))); } -void InputFilter::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { +void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; @@ -155,7 +155,7 @@ void InputFilter::get_argument_options(const StringName &p_function, int p_idx, #endif } -void InputFilter::SpeedTrack::update(const Vector2 &p_delta_p) { +void Input::SpeedTrack::update(const Vector2 &p_delta_p) { uint64_t tick = OS::get_singleton()->get_ticks_usec(); uint32_t tdiff = tick - last_tick; @@ -179,26 +179,26 @@ void InputFilter::SpeedTrack::update(const Vector2 &p_delta_p) { } } -void InputFilter::SpeedTrack::reset() { +void Input::SpeedTrack::reset() { last_tick = OS::get_singleton()->get_ticks_usec(); speed = Vector2(); accum_t = 0; } -InputFilter::SpeedTrack::SpeedTrack() { +Input::SpeedTrack::SpeedTrack() { min_ref_frame = 0.1; max_ref_frame = 0.3; reset(); } -bool InputFilter::is_key_pressed(int p_keycode) const { +bool Input::is_key_pressed(int p_keycode) const { _THREAD_SAFE_METHOD_ return keys_pressed.has(p_keycode); } -bool InputFilter::is_mouse_button_pressed(int p_button) const { +bool Input::is_mouse_button_pressed(int p_button) const { _THREAD_SAFE_METHOD_ return (mouse_button_mask & (1 << (p_button - 1))) != 0; @@ -209,18 +209,18 @@ static int _combine_device(int p_value, int p_device) { return p_value | (p_device << 20); } -bool InputFilter::is_joy_button_pressed(int p_device, int p_button) const { +bool Input::is_joy_button_pressed(int p_device, int p_button) const { _THREAD_SAFE_METHOD_ return joy_buttons_pressed.has(_combine_device(p_button, p_device)); } -bool InputFilter::is_action_pressed(const StringName &p_action) const { +bool Input::is_action_pressed(const StringName &p_action) const { return action_state.has(p_action) && action_state[p_action].pressed; } -bool InputFilter::is_action_just_pressed(const StringName &p_action) const { +bool Input::is_action_just_pressed(const StringName &p_action) const { const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) @@ -233,7 +233,7 @@ bool InputFilter::is_action_just_pressed(const StringName &p_action) const { } } -bool InputFilter::is_action_just_released(const StringName &p_action) const { +bool Input::is_action_just_released(const StringName &p_action) const { const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) @@ -246,7 +246,7 @@ bool InputFilter::is_action_just_released(const StringName &p_action) const { } } -float InputFilter::get_action_strength(const StringName &p_action) const { +float Input::get_action_strength(const StringName &p_action) const { const Map<StringName, Action>::Element *E = action_state.find(p_action); if (!E) return 0.0f; @@ -254,7 +254,7 @@ float InputFilter::get_action_strength(const StringName &p_action) const { return E->get().strength; } -float InputFilter::get_joy_axis(int p_device, int p_axis) const { +float Input::get_joy_axis(int p_device, int p_axis) const { _THREAD_SAFE_METHOD_ int c = _combine_device(p_axis, p_device); @@ -265,13 +265,13 @@ float InputFilter::get_joy_axis(int p_device, int p_axis) const { } } -String InputFilter::get_joy_name(int p_idx) { +String Input::get_joy_name(int p_idx) { _THREAD_SAFE_METHOD_ return joy_names[p_idx].name; }; -Vector2 InputFilter::get_joy_vibration_strength(int p_device) { +Vector2 Input::get_joy_vibration_strength(int p_device) { if (joy_vibration.has(p_device)) { return Vector2(joy_vibration[p_device].weak_magnitude, joy_vibration[p_device].strong_magnitude); } else { @@ -279,7 +279,7 @@ Vector2 InputFilter::get_joy_vibration_strength(int p_device) { } } -uint64_t InputFilter::get_joy_vibration_timestamp(int p_device) { +uint64_t Input::get_joy_vibration_timestamp(int p_device) { if (joy_vibration.has(p_device)) { return joy_vibration[p_device].timestamp; } else { @@ -287,7 +287,7 @@ uint64_t InputFilter::get_joy_vibration_timestamp(int p_device) { } } -float InputFilter::get_joy_vibration_duration(int p_device) { +float Input::get_joy_vibration_duration(int p_device) { if (joy_vibration.has(p_device)) { return joy_vibration[p_device].duration; } else { @@ -307,7 +307,7 @@ static String _hex_str(uint8_t p_byte) { return ret; }; -void InputFilter::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) { +void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) { _THREAD_SAFE_METHOD_ Joypad js; @@ -349,36 +349,36 @@ void InputFilter::joy_connection_changed(int p_idx, bool p_connected, String p_n emit_signal("joy_connection_changed", p_idx, p_connected); }; -Vector3 InputFilter::get_gravity() const { +Vector3 Input::get_gravity() const { _THREAD_SAFE_METHOD_ return gravity; } -Vector3 InputFilter::get_accelerometer() const { +Vector3 Input::get_accelerometer() const { _THREAD_SAFE_METHOD_ return accelerometer; } -Vector3 InputFilter::get_magnetometer() const { +Vector3 Input::get_magnetometer() const { _THREAD_SAFE_METHOD_ return magnetometer; } -Vector3 InputFilter::get_gyroscope() const { +Vector3 Input::get_gyroscope() const { _THREAD_SAFE_METHOD_ return gyroscope; } -void InputFilter::parse_input_event(const Ref<InputEvent> &p_event) { +void Input::parse_input_event(const Ref<InputEvent> &p_event) { _parse_input_event_impl(p_event, false); } -void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { +void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { // Notes on mouse-touch emulation: // - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects @@ -561,14 +561,14 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p event_dispatch_function(p_event); } -void InputFilter::set_joy_axis(int p_device, int p_axis, float p_value) { +void Input::set_joy_axis(int p_device, int p_axis, float p_value) { _THREAD_SAFE_METHOD_ int c = _combine_device(p_axis, p_device); _joy_axis[c] = p_value; } -void InputFilter::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) { +void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) { _THREAD_SAFE_METHOD_ if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) { return; @@ -581,7 +581,7 @@ void InputFilter::start_joy_vibration(int p_device, float p_weak_magnitude, floa joy_vibration[p_device] = vibration; } -void InputFilter::stop_joy_vibration(int p_device) { +void Input::stop_joy_vibration(int p_device) { _THREAD_SAFE_METHOD_ VibrationInfo vibration; vibration.weak_magnitude = 0; @@ -591,63 +591,63 @@ void InputFilter::stop_joy_vibration(int p_device) { joy_vibration[p_device] = vibration; } -void InputFilter::vibrate_handheld(int p_duration_ms) { +void Input::vibrate_handheld(int p_duration_ms) { OS::get_singleton()->vibrate_handheld(p_duration_ms); } -void InputFilter::set_gravity(const Vector3 &p_gravity) { +void Input::set_gravity(const Vector3 &p_gravity) { _THREAD_SAFE_METHOD_ gravity = p_gravity; } -void InputFilter::set_accelerometer(const Vector3 &p_accel) { +void Input::set_accelerometer(const Vector3 &p_accel) { _THREAD_SAFE_METHOD_ accelerometer = p_accel; } -void InputFilter::set_magnetometer(const Vector3 &p_magnetometer) { +void Input::set_magnetometer(const Vector3 &p_magnetometer) { _THREAD_SAFE_METHOD_ magnetometer = p_magnetometer; } -void InputFilter::set_gyroscope(const Vector3 &p_gyroscope) { +void Input::set_gyroscope(const Vector3 &p_gyroscope) { _THREAD_SAFE_METHOD_ gyroscope = p_gyroscope; } -void InputFilter::set_mouse_position(const Point2 &p_posf) { +void Input::set_mouse_position(const Point2 &p_posf) { mouse_speed_track.update(p_posf - mouse_pos); mouse_pos = p_posf; } -Point2 InputFilter::get_mouse_position() const { +Point2 Input::get_mouse_position() const { return mouse_pos; } -Point2 InputFilter::get_last_mouse_speed() const { +Point2 Input::get_last_mouse_speed() const { return mouse_speed_track.speed; } -int InputFilter::get_mouse_button_mask() const { +int Input::get_mouse_button_mask() const { return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state(); } -void InputFilter::warp_mouse_position(const Vector2 &p_to) { +void Input::warp_mouse_position(const Vector2 &p_to) { warp_mouse_func(p_to); } -Point2i InputFilter::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) { +Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) { // The relative distance reported for the next event after a warp is in the boundaries of the // size of the rect on that axis, but it may be greater, in which case there's not problem as fmod() @@ -673,10 +673,10 @@ Point2i InputFilter::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motio return rel_warped; } -void InputFilter::iteration(float p_step) { +void Input::iteration(float p_step) { } -void InputFilter::action_press(const StringName &p_action, float p_strength) { +void Input::action_press(const StringName &p_action, float p_strength) { Action action; @@ -688,7 +688,7 @@ void InputFilter::action_press(const StringName &p_action, float p_strength) { action_state[p_action] = action; } -void InputFilter::action_release(const StringName &p_action) { +void Input::action_release(const StringName &p_action) { Action action; @@ -700,19 +700,19 @@ void InputFilter::action_release(const StringName &p_action) { action_state[p_action] = action; } -void InputFilter::set_emulate_touch_from_mouse(bool p_emulate) { +void Input::set_emulate_touch_from_mouse(bool p_emulate) { emulate_touch_from_mouse = p_emulate; } -bool InputFilter::is_emulating_touch_from_mouse() const { +bool Input::is_emulating_touch_from_mouse() const { return emulate_touch_from_mouse; } // Calling this whenever the game window is focused helps unstucking the "touch mouse" // if the OS or its abstraction class hasn't properly reported that touch pointers raised -void InputFilter::ensure_touch_mouse_raised() { +void Input::ensure_touch_mouse_raised() { if (mouse_from_touch_index != -1) { mouse_from_touch_index = -1; @@ -731,22 +731,22 @@ void InputFilter::ensure_touch_mouse_raised() { } } -void InputFilter::set_emulate_mouse_from_touch(bool p_emulate) { +void Input::set_emulate_mouse_from_touch(bool p_emulate) { emulate_mouse_from_touch = p_emulate; } -bool InputFilter::is_emulating_mouse_from_touch() const { +bool Input::is_emulating_mouse_from_touch() const { return emulate_mouse_from_touch; } -InputFilter::CursorShape InputFilter::get_default_cursor_shape() const { +Input::CursorShape Input::get_default_cursor_shape() const { return default_shape; } -void InputFilter::set_default_cursor_shape(CursorShape p_shape) { +void Input::set_default_cursor_shape(CursorShape p_shape) { if (default_shape == p_shape) return; @@ -761,19 +761,19 @@ void InputFilter::set_default_cursor_shape(CursorShape p_shape) { parse_input_event(mm); } -InputFilter::CursorShape InputFilter::get_current_cursor_shape() const { +Input::CursorShape Input::get_current_cursor_shape() const { return get_current_cursor_shape_func(); } -void InputFilter::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (Engine::get_singleton()->is_editor_hint()) return; set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot); } -void InputFilter::accumulate_input_event(const Ref<InputEvent> &p_event) { +void Input::accumulate_input_event(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); if (!use_accumulated_input) { @@ -786,7 +786,7 @@ void InputFilter::accumulate_input_event(const Ref<InputEvent> &p_event) { accumulated_events.push_back(p_event); } -void InputFilter::flush_accumulated_events() { +void Input::flush_accumulated_events() { while (accumulated_events.front()) { parse_input_event(accumulated_events.front()->get()); @@ -794,12 +794,12 @@ void InputFilter::flush_accumulated_events() { } } -void InputFilter::set_use_accumulated_input(bool p_enable) { +void Input::set_use_accumulated_input(bool p_enable) { use_accumulated_input = p_enable; } -void InputFilter::release_pressed_events() { +void Input::release_pressed_events() { flush_accumulated_events(); // this is needed to release actions strengths @@ -807,17 +807,17 @@ void InputFilter::release_pressed_events() { joy_buttons_pressed.clear(); _joy_axis.clear(); - for (Map<StringName, InputFilter::Action>::Element *E = action_state.front(); E; E = E->next()) { + for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) { if (E->get().pressed) action_release(E->key()); } } -void InputFilter::set_event_dispatch_function(EventDispatchFunc p_function) { +void Input::set_event_dispatch_function(EventDispatchFunc p_function) { event_dispatch_function = p_function; } -void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) { +void Input::joy_button(int p_device, int p_button, bool p_pressed) { _THREAD_SAFE_METHOD_; Joypad &joy = joy_names[p_device]; @@ -856,7 +856,7 @@ void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) { // no event? } -void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { +void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { _THREAD_SAFE_METHOD_; @@ -971,7 +971,7 @@ void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { //printf("invalid mapping\n"); } -void InputFilter::joy_hat(int p_device, int p_val) { +void Input::joy_hat(int p_device, int p_val) { _THREAD_SAFE_METHOD_; const Joypad &joy = joy_names[p_device]; @@ -1003,7 +1003,7 @@ void InputFilter::joy_hat(int p_device, int p_val) { joy_names[p_device].hat_current = p_val; } -void InputFilter::_button_event(int p_device, int p_index, bool p_pressed) { +void Input::_button_event(int p_device, int p_index, bool p_pressed) { Ref<InputEventJoypadButton> ievent; ievent.instance(); @@ -1014,7 +1014,7 @@ void InputFilter::_button_event(int p_device, int p_index, bool p_pressed) { parse_input_event(ievent); } -void InputFilter::_axis_event(int p_device, int p_axis, float p_value) { +void Input::_axis_event(int p_device, int p_axis, float p_value) { Ref<InputEventJoypadMotion> ievent; ievent.instance(); @@ -1025,7 +1025,7 @@ void InputFilter::_axis_event(int p_device, int p_axis, float p_value) { parse_input_event(ievent); }; -InputFilter::JoyEvent InputFilter::_find_to_event(String p_to) { +Input::JoyEvent Input::_find_to_event(String p_to) { // string names of the SDL buttons in the same order as input_event.h godot buttons static const char *buttons[] = { "a", "b", "x", "y", "leftshoulder", "rightshoulder", "lefttrigger", "righttrigger", "leftstick", "rightstick", "back", "start", "dpup", "dpdown", "dpleft", "dpright", "guide", nullptr }; @@ -1063,7 +1063,7 @@ InputFilter::JoyEvent InputFilter::_find_to_event(String p_to) { return ret; }; -void InputFilter::parse_mapping(String p_mapping) { +void Input::parse_mapping(String p_mapping) { _THREAD_SAFE_METHOD_; JoyDeviceMapping mapping; @@ -1128,7 +1128,7 @@ void InputFilter::parse_mapping(String p_mapping) { //printf("added mapping with uuid %ls\n", mapping.uid.c_str()); }; -void InputFilter::add_joy_mapping(String p_mapping, bool p_update_existing) { +void Input::add_joy_mapping(String p_mapping, bool p_update_existing) { parse_mapping(p_mapping); if (p_update_existing) { Vector<String> entry = p_mapping.split(","); @@ -1141,7 +1141,7 @@ void InputFilter::add_joy_mapping(String p_mapping, bool p_update_existing) { } } -void InputFilter::remove_joy_mapping(String p_guid) { +void Input::remove_joy_mapping(String p_guid) { for (int i = map_db.size() - 1; i >= 0; i--) { if (p_guid == map_db[i].uid) { map_db.remove(i); @@ -1154,7 +1154,7 @@ void InputFilter::remove_joy_mapping(String p_guid) { } } -void InputFilter::set_fallback_mapping(String p_guid) { +void Input::set_fallback_mapping(String p_guid) { for (int i = 0; i < map_db.size(); i++) { if (map_db[i].uid == p_guid) { @@ -1165,17 +1165,17 @@ void InputFilter::set_fallback_mapping(String p_guid) { } //platforms that use the remapping system can override and call to these ones -bool InputFilter::is_joy_known(int p_device) { +bool Input::is_joy_known(int p_device) { int mapping = joy_names[p_device].mapping; return mapping != -1 ? (mapping != fallback_mapping) : false; } -String InputFilter::get_joy_guid(int p_device) const { +String Input::get_joy_guid(int p_device) const { ERR_FAIL_COND_V(!joy_names.has(p_device), ""); return joy_names[p_device].uid; } -Array InputFilter::get_connected_joypads() { +Array Input::get_connected_joypads() { Array ret; Map<int, Joypad>::Element *elem = joy_names.front(); while (elem) { @@ -1219,12 +1219,12 @@ static const char *_axes[JOY_AXIS_MAX] = { "" }; -String InputFilter::get_joy_button_string(int p_button) { +String Input::get_joy_button_string(int p_button) { ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, ""); return _buttons[p_button]; } -int InputFilter::get_joy_button_index_from_string(String p_button) { +int Input::get_joy_button_index_from_string(String p_button) { for (int i = 0; i < JOY_BUTTON_MAX; i++) { if (p_button == _buttons[i]) { return i; @@ -1233,7 +1233,7 @@ int InputFilter::get_joy_button_index_from_string(String p_button) { ERR_FAIL_V(-1); } -int InputFilter::get_unused_joy_id() { +int Input::get_unused_joy_id() { for (int i = 0; i < JOYPADS_MAX; i++) { if (!joy_names.has(i) || !joy_names[i].connected) { return i; @@ -1242,12 +1242,12 @@ int InputFilter::get_unused_joy_id() { return -1; } -String InputFilter::get_joy_axis_string(int p_axis) { +String Input::get_joy_axis_string(int p_axis) { ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, ""); return _axes[p_axis]; } -int InputFilter::get_joy_axis_index_from_string(String p_axis) { +int Input::get_joy_axis_index_from_string(String p_axis) { for (int i = 0; i < JOY_AXIS_MAX; i++) { if (p_axis == _axes[i]) { return i; @@ -1256,7 +1256,7 @@ int InputFilter::get_joy_axis_index_from_string(String p_axis) { ERR_FAIL_V(-1); } -InputFilter::InputFilter() { +Input::Input() { singleton = this; use_accumulated_input = true; diff --git a/core/input/input_filter.h b/core/input/input.h index 908a005228..477de1e879 100644 --- a/core/input/input_filter.h +++ b/core/input/input.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* input_filter.h */ +/* input.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -35,12 +35,12 @@ #include "core/object.h" #include "core/os/thread_safe.h" -class InputFilter : public Object { +class Input : public Object { - GDCLASS(InputFilter, Object); + GDCLASS(Input, Object); _THREAD_SAFE_CLASS_ - static InputFilter *singleton; + static Input *singleton; public: enum MouseMode { @@ -239,7 +239,7 @@ public: MouseMode get_mouse_mode() const; void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const; - static InputFilter *get_singleton(); + static Input *get_singleton(); bool is_key_pressed(int p_keycode) const; bool is_mouse_button_pressed(int p_button) const; @@ -299,7 +299,7 @@ public: CursorShape get_default_cursor_shape() const; void set_default_cursor_shape(CursorShape p_shape); CursorShape get_current_cursor_shape() const; - void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = InputFilter::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); + void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()); void parse_mapping(String p_mapping); void joy_button(int p_device, int p_button, bool p_pressed); @@ -328,10 +328,10 @@ public: void set_event_dispatch_function(EventDispatchFunc p_function); - InputFilter(); + Input(); }; -VARIANT_ENUM_CAST(InputFilter::MouseMode); -VARIANT_ENUM_CAST(InputFilter::CursorShape); +VARIANT_ENUM_CAST(Input::MouseMode); +VARIANT_ENUM_CAST(Input::CursorShape); #endif // INPUT_H diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 80219331c0..d18adb1983 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -477,7 +477,7 @@ void InputEventMouseButton::set_factor(float p_factor) { factor = p_factor; } -float InputEventMouseButton::get_factor() { +float InputEventMouseButton::get_factor() const { return factor; } diff --git a/core/input/input_event.h b/core/input/input_event.h index 2fdcdd0319..8774b3b1db 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -349,7 +349,7 @@ protected: public: void set_factor(float p_factor); - float get_factor(); + float get_factor() const; void set_button_index(int p_index); int get_button_index() const; diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index aa10afe642..0a7dee9444 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -30,16 +30,15 @@ #include "file_access_pack.h" -#include "core/project_settings.h" #include "core/version.h" #include <stdio.h> -Error PackedData::add_pack(const String &p_path, bool p_replace_files, const String &p_destination) { +Error PackedData::add_pack(const String &p_path, bool p_replace_files) { for (int i = 0; i < sources.size(); i++) { - if (sources[i]->try_open_pack(p_path, p_replace_files, p_destination)) { + if (sources[i]->try_open_pack(p_path, p_replace_files)) { return OK; }; @@ -90,7 +89,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o } } String filename = path.get_file(); - // Don't add as a file if the path points to a directory. + // Don't add as a file if the path points to a directory if (!filename.empty()) { cd->files.insert(filename); } @@ -133,7 +132,7 @@ PackedData::~PackedData() { ////////////////////////////////////////////////////////////////// -bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) { +bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) @@ -199,24 +198,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, String path; path.parse_utf8(cs.ptr()); - if (p_destination != "") { - String destination = ProjectSettings::get_singleton()->localize_path(p_destination); - ERR_FAIL_COND_V_MSG(!destination.begins_with("res://"), false, "The destination path must be within the resource filesystem (res://)."); - - if (!destination.ends_with("/")) { - destination += "/"; - } - - DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES); - if (!dir->dir_exists(destination)) { - memdelete(dir); - - ERR_FAIL_V_MSG(false, vformat("The destination path \"%s\" does not exist.", destination)); - } - memdelete(dir); - - path = path.replace_first("res://", destination); - } uint64_t ofs = f->get_64(); uint64_t size = f->get_64(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 1a46bef0f6..8df6826ac9 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -113,7 +113,7 @@ public: _FORCE_INLINE_ bool is_disabled() const { return disabled; } static PackedData *get_singleton() { return singleton; } - Error add_pack(const String &p_path, bool p_replace_files, const String &p_destination); + Error add_pack(const String &p_path, bool p_replace_files); _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); @@ -125,7 +125,7 @@ public: class PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "") = 0; + virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0; virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; virtual ~PackSource() {} }; @@ -133,7 +133,7 @@ public: class PackedSourcePCK : public PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = ""); + virtual bool try_open_pack(const String &p_path, bool p_replace_files); virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); }; diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 5696e47193..57de66afaf 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -160,7 +160,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { return pkg; } -bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) { +bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) { //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) @@ -206,26 +206,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const f.package = pkg_num; unzGetFilePos(zfile, &f.file_pos); - String fname; - if (p_destination != "") { - String destination = "res://" + p_destination; - if (!destination.ends_with("/")) { - destination += "/"; - } - - DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES); - if (!dir->dir_exists(destination)) { - memdelete(dir); - - return false; - } - memdelete(dir); - - fname = destination + filename_inzip; - } else { - fname = String("res://") + filename_inzip; - } - + String fname = String("res://") + filename_inzip; files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 5bcaea7ed9..d5ce7d7a8d 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -74,7 +74,7 @@ public: bool file_exists(String p_name) const; - virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = ""); + virtual bool try_open_pack(const String &p_path, bool p_replace_files); FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); static ZipArchive *get_singleton(); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 2770adbd36..01e6bb5618 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -129,7 +129,7 @@ void ImageLoader::cleanup() { ///////////////// -RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 18b4df98f7..15ce6031d7 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -73,7 +73,7 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index a640565ecf..8c7559479b 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -337,12 +337,16 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index = f->get_32(); - String path = res_path + "::" + itos(index); - RES res = ResourceLoader::load(path); - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); + if (use_nocache) { + r_v = internal_resources[index].cache; + } else { + String path = res_path + "::" + itos(index); + RES res = ResourceLoader::load(path); + if (res.is_null()) { + WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); + } + r_v = res; } - r_v = res; } break; case OBJECT_EXTERNAL_RESOURCE: { @@ -716,22 +720,24 @@ Error ResourceLoaderBinary::load() { if (!main) { - path = internal_resources[i].path; - if (path.begins_with("local://")) { - path = path.replace_first("local://", ""); - subindex = path.to_int(); - path = res_path + "::" + path; - } + if (!use_nocache) { + path = internal_resources[i].path; + if (path.begins_with("local://")) { + path = path.replace_first("local://", ""); + subindex = path.to_int(); + path = res_path + "::" + path; + } - if (ResourceCache::has(path)) { - //already loaded, don't do anything - stage++; - error = OK; - continue; + if (ResourceCache::has(path)) { + //already loaded, don't do anything + stage++; + error = OK; + continue; + } } } else { - if (!ResourceCache::has(res_path)) + if (!use_nocache && !ResourceCache::has(res_path)) path = res_path; } @@ -757,9 +763,15 @@ Error ResourceLoaderBinary::load() { RES res = RES(r); - r->set_path(path); + if (path != String()) { + r->set_path(path); + } r->set_subindex(subindex); + if (!main) { + internal_resources.write[i].cache = res; + } + int pc = f->get_32(); //set properties @@ -1013,6 +1025,7 @@ ResourceLoaderBinary::ResourceLoaderBinary() : importmd_ofs(0), error(OK) { + use_nocache = false; progress = nullptr; use_sub_threads = false; } @@ -1023,7 +1036,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() { memdelete(f); } -RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; @@ -1034,6 +1047,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); ResourceLoaderBinary loader; + loader.use_nocache = p_no_cache; loader.use_sub_threads = p_use_sub_threads; loader.progress = r_progress; String path = p_original_path != "" ? p_original_path : p_path; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index da67e1e648..0f8fc9445b 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -68,6 +68,7 @@ class ResourceLoaderBinary { struct IntResource { String path; uint64_t offset; + RES cache; }; Vector<IntResource> internal_resources; @@ -78,6 +79,8 @@ class ResourceLoaderBinary { Map<String, String> remaps; Error error; + bool use_nocache; + friend class ResourceFormatLoaderBinary; Error parse_variant(Variant &r_v); @@ -101,7 +104,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index ceb73cab77..643df53f8c 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -117,7 +117,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return OK; } -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -130,7 +130,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error, p_use_sub_threads, r_progress); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index dbac80599a..6b76912494 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -58,7 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 05a41013c2..d90802d7e2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -119,7 +119,7 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } } -RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (get_script_instance() && get_script_instance()->has_method("load")) { Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads); @@ -200,7 +200,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress); + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache); if (res.is_null()) { continue; } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index be4adf9091..2d95d5545f 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -43,7 +43,7 @@ protected: static void _bind_methods(); public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual bool exists(const String &p_path) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 5da236d029..bce5361c76 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -185,7 +185,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { return translation; } -RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 9d3117b630..137dfd1768 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -38,7 +38,7 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: static RES load_translation(FileAccess *f, Error *r_error = nullptr); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index f4259e388b..f46badd19e 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -119,11 +119,11 @@ Vector2 Vector2::round() const { } Vector2 Vector2::rotated(real_t p_by) const { - - Vector2 v; - v.set_rotation(angle() + p_by); - v *= length(); - return v; + real_t sine = Math::sin(p_by); + real_t cosi = Math::cos(p_by); + return Vector2( + x * cosi - y * sine, + x * sine + y * cosi); } Vector2 Vector2::posmod(const real_t p_mod) const { diff --git a/core/math/vector2.h b/core/math/vector2.h index ba5558102f..95d2474838 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -123,12 +123,6 @@ struct Vector2 { real_t angle() const; - void set_rotation(real_t p_radians) { - - x = Math::cos(p_radians); - y = Math::sin(p_radians); - } - _FORCE_INLINE_ Vector2 abs() const { return Vector2(Math::abs(x), Math::abs(y)); diff --git a/core/method_bind.h b/core/method_bind.h index 588b472b62..d39f107ba6 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -39,6 +39,7 @@ #include "core/method_ptrcall.h" #include "core/object.h" #include "core/type_info.h" +#include "core/typedefs.h" #include "core/variant.h" #include <stdio.h> diff --git a/core/object.h b/core/object.h index 1eaab5034e..b40aef2a42 100644 --- a/core/object.h +++ b/core/object.h @@ -91,6 +91,7 @@ enum PropertyHint { PROPERTY_HINT_NODE_PATH_VALID_TYPES, PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog PROPERTY_HINT_INT_IS_OBJECTID, + PROPERTY_HINT_ARRAY_TYPE, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp index 985f6f38e5..efd87d3ab6 100644 --- a/core/os/midi_driver.cpp +++ b/core/os/midi_driver.cpp @@ -30,7 +30,7 @@ #include "midi_driver.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" uint8_t MIDIDriver::last_received_message = 0x00; @@ -117,7 +117,7 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_ break; } - InputFilter *id = InputFilter::get_singleton(); + Input *id = Input::get_singleton(); id->parse_input_event(event); } diff --git a/core/os/os.cpp b/core/os/os.cpp index 0636810e4b..425132fbec 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -30,7 +30,7 @@ #include "os.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/midi_driver.h" diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 201ab8e90a..63b52661b4 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -268,12 +268,12 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const { } } -bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, const String &p_destination) { +bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files) { if (PackedData::get_singleton()->is_disabled()) return false; - bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_destination) == OK; + bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files) == OK; if (!ok) return false; @@ -990,7 +990,7 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path); ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path); ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save); - ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "destination"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL("")); + ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files"), &ProjectSettings::_load_resource_pack, DEFVAL(true)); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert); diff --git a/core/project_settings.h b/core/project_settings.h index 6e6b2fe4c7..7b3ca18c62 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -104,7 +104,7 @@ protected: void _convert_to_last_version(int p_from_version); - bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, const String &p_destination = ""); + bool _load_resource_pack(const String &p_pack, bool p_replace_files = true); void _add_property_info_bind(const Dictionary &p_info); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 905f43d61b..23f549be1a 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -38,7 +38,7 @@ #include "core/crypto/hashing_context.h" #include "core/engine.h" #include "core/func_ref.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/io/config_file.h" #include "core/io/dtls_server.h" @@ -249,7 +249,7 @@ void register_core_singletons() { ClassDB::register_class<_ClassDB>(); ClassDB::register_class<_Marshalls>(); ClassDB::register_class<TranslationServer>(); - ClassDB::register_virtual_class<InputFilter>(); + ClassDB::register_virtual_class<Input>(); ClassDB::register_class<InputMap>(); ClassDB::register_class<_JSON>(); ClassDB::register_class<Expression>(); @@ -264,7 +264,7 @@ void register_core_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb)); Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("Input", InputFilter::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton())); } diff --git a/core/script_language.h b/core/script_language.h index 2d86c5166d..5cc240efcb 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -135,6 +135,8 @@ public: virtual Ref<Script> get_base_script() const = 0; //for script inheritance + virtual bool inherits_script(const Ref<Script> &p_script) const = 0; + virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so virtual ScriptInstance *instance_create(Object *p_this) = 0; virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) { return nullptr; } diff --git a/core/typed_array.cpp b/core/typed_array.cpp new file mode 100644 index 0000000000..55e45f0b3f --- /dev/null +++ b/core/typed_array.cpp @@ -0,0 +1 @@ +#include "typed_array.h" diff --git a/core/typed_array.h b/core/typed_array.h new file mode 100644 index 0000000000..5e95e81ea3 --- /dev/null +++ b/core/typed_array.h @@ -0,0 +1,202 @@ +#ifndef TYPED_ARRAY_H +#define TYPED_ARRAY_H + +#include "core/array.h" +#include "core/method_ptrcall.h" +#include "core/variant.h" + +template <class T> +class TypedArray : public Array { +public: + template <class U> + _FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) { + static_assert(__is_base_of(T, U)); + _assign(p_array); + } + + _FORCE_INLINE_ void operator=(const Array &p_array) { + _assign(p_array); + } + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : + Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) { + } + _FORCE_INLINE_ TypedArray(const Array &p_array) : + Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) { + } + _FORCE_INLINE_ TypedArray() { + set_typed(Variant::OBJECT, T::get_class_static(), Variant()); + } +}; + +//specialization for the rest of variant types + +#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \ + template <> \ + class TypedArray<m_type> : public Array { \ + public: \ + _FORCE_INLINE_ void operator=(const Array &p_array) { \ + _assign(p_array); \ + } \ + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \ + Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray(const Array &p_array) : \ + Array(p_array, m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray() { \ + set_typed(m_variant_type, StringName(), Variant()); \ + } \ + }; + +MAKE_TYPED_ARRAY(bool, Variant::BOOL) +MAKE_TYPED_ARRAY(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY(int8_t, Variant::INT) +MAKE_TYPED_ARRAY(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY(int16_t, Variant::INT) +MAKE_TYPED_ARRAY(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY(int32_t, Variant::INT) +MAKE_TYPED_ARRAY(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY(int64_t, Variant::INT) +MAKE_TYPED_ARRAY(float, Variant::FLOAT) +MAKE_TYPED_ARRAY(double, Variant::FLOAT) +MAKE_TYPED_ARRAY(String, Variant::STRING) +MAKE_TYPED_ARRAY(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY(AABB, Variant::AABB) +MAKE_TYPED_ARRAY(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY(Color, Variant::COLOR) +MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY(RID, Variant::_RID) +MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#ifdef PTRCALL_ENABLED + +template <class T> +struct PtrToArg<TypedArray<T>> { + + _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + + return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); + } + + _FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) { + + *(Array *)p_ptr = p_val; + } +}; + +template <class T> +struct PtrToArg<const TypedArray<T> &> { + + _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + + return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); + } +}; + +#endif // PTRCALL_ENABLED + +#ifdef DEBUG_METHODS_ENABLED + +template <class T> +struct GetTypeInfo<TypedArray<T>> { + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); + } +}; + +template <class T> +struct GetTypeInfo<const TypedArray<T> &> { + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); + } +}; + +#define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type) \ + template <> \ + struct GetTypeInfo<TypedArray<m_type>> { \ + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const TypedArray<m_type> &> { \ + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ + } \ + }; + +MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL) +MAKE_TYPED_ARRAY_INFO(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(float, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(double, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(String, Variant::STRING) +MAKE_TYPED_ARRAY_INFO(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY_INFO(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY_INFO(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB) +MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR) +MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID) +MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#endif + +#endif // TYPED_ARRAY_H diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index f462aa989d..47b9c80f3f 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -12,9 +12,6 @@ <methods> </methods> <members> - <member name="XRServer" type="XRServer" setter="" getter=""> - The [XRServer] singleton. - </member> <member name="AudioServer" type="AudioServer" setter="" getter=""> The [AudioServer] singleton. </member> @@ -24,20 +21,20 @@ <member name="ClassDB" type="ClassDB" setter="" getter=""> The [ClassDB] singleton. </member> + <member name="DisplayServer" type="DisplayServer" setter="" getter=""> + The [DisplayServer] singleton. + </member> <member name="Engine" type="Engine" setter="" getter=""> The [Engine] singleton. </member> <member name="Geometry" type="Geometry" setter="" getter=""> The [Geometry] singleton. </member> - <member name="GodotSharp" type="GodotSharp" setter="" getter=""> - The [GodotSharp] singleton. Only available when using Godot's Mono build. - </member> <member name="IP" type="IP" setter="" getter=""> The [IP] singleton. </member> - <member name="Input" type="InputFilter" setter="" getter=""> - The [InputFilter] singleton. + <member name="Input" type="Input" setter="" getter=""> + The [Input] singleton. </member> <member name="InputMap" type="InputMap" setter="" getter=""> The [InputMap] singleton. @@ -95,6 +92,9 @@ <member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter=""> The [VisualScriptEditor] singleton. </member> + <member name="XRServer" type="XRServer" setter="" getter=""> + The [XRServer] singleton. + </member> </members> <constants> <constant name="MARGIN_LEFT" value="0" enum="Margin"> @@ -1345,52 +1345,52 @@ <constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint"> Deprecated hint, unused. </constant> - <constant name="PROPERTY_HINT_KEY_ACCEL" value="7" enum="PropertyHint"> + <constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint"> Deprecated hint, unused. </constant> - <constant name="PROPERTY_HINT_FLAGS" value="8" enum="PropertyHint"> + <constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint"> Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code]. </constant> - <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="9" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 2D render layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="10" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 2D physics layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 3D render layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 3D physics layers. </constant> - <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint"> + <constant name="PROPERTY_HINT_FILE" value="12" enum="PropertyHint"> Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. </constant> - <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint"> + <constant name="PROPERTY_HINT_DIR" value="13" enum="PropertyHint"> Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path. </constant> - <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint"> + <constant name="PROPERTY_HINT_GLOBAL_FILE" value="14" enum="PropertyHint"> Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. </constant> - <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint"> + <constant name="PROPERTY_HINT_GLOBAL_DIR" value="15" enum="PropertyHint"> Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path. </constant> - <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint"> + <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="16" enum="PropertyHint"> Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate. </constant> - <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint"> + <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="17" enum="PropertyHint"> Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed. </constant> - <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint"> + <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="18" enum="PropertyHint"> Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use. </constant> - <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint"> + <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="19" enum="PropertyHint"> Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited. </constant> - <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint"> + <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="20" enum="PropertyHint"> Hints that an image is compressed using lossy compression. </constant> - <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint"> + <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="21" enum="PropertyHint"> Hints that an image is compressed using lossless compression. </constant> <constant name="PROPERTY_USAGE_STORAGE" value="1" enum="PropertyUsageFlags"> @@ -1420,6 +1420,9 @@ <constant name="PROPERTY_USAGE_CATEGORY" value="256" enum="PropertyUsageFlags"> Used to categorize properties together in the editor. </constant> + <constant name="PROPERTY_USAGE_SUBGROUP" value="512" enum="PropertyUsageFlags"> + Used to group properties together in the editor in a subgroup (under a group). + </constant> <constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="2048" enum="PropertyUsageFlags"> The property does not save its state in [PackedScene]. </constant> diff --git a/doc/classes/AnimatedTexture.xml b/doc/classes/AnimatedTexture.xml index 80b910aaa7..ddd51cc6b3 100644 --- a/doc/classes/AnimatedTexture.xml +++ b/doc/classes/AnimatedTexture.xml @@ -61,6 +61,9 @@ </method> </methods> <members> + <member name="current_frame" type="int" setter="set_current_frame" getter="get_current_frame"> + Sets the currently visible frame of the texture. + </member> <member name="fps" type="float" setter="set_fps" getter="get_fps" default="4.0"> Animation speed in frames per second. This value defines the default time interval between two frames of the animation, and thus the overall duration of the animation loop based on the [member frames] property. A value of 0 means no predefined number of frames per second, the animation will play according to each frame's frame delay (see [method set_frame_delay]). For example, an animation with 8 frames, no frame delay and a [code]fps[/code] value of 2 will run for 4 seconds, with each frame lasting 0.5 seconds. @@ -68,6 +71,12 @@ <member name="frames" type="int" setter="set_frames" getter="get_frames" default="1"> Number of frames to use in the animation. While you can create the frames independently with [method set_frame_texture], you need to set this value for the animation to take new frames into account. The maximum number of frames is [constant MAX_FRAMES]. </member> + <member name="oneshot" type="bool" setter="set_oneshot" getter="get_oneshot" default="false"> + If [code]true[/code], the animation will only play once and will not loop back to the first frame after reaching the end. Note that reaching the end will not set [member pause] to [code]true[/code]. + </member> + <member name="pause" type="bool" setter="set_pause" getter="get_pause" default="false"> + If [code]true[/code], the animation will pause where it currently is (i.e. at [member current_frame]). The animation will continue from where it was paused when changing this property to [code]false[/code]. + </member> </members> <constants> <constant name="MAX_FRAMES" value="256"> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 0c1317f19d..4190cbe6b9 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -29,14 +29,14 @@ </description> </method> <method name="get_overlapping_areas" qualifiers="const"> - <return type="Array"> + <return type="Area2D[]"> </return> <description> Returns a list of intersecting [Area2D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead. </description> </method> <method name="get_overlapping_bodies" qualifiers="const"> - <return type="Array"> + <return type="Node2D[]"> </return> <description> Returns a list of intersecting [PhysicsBody2D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead. diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml index 1adfc878e2..a94cecd879 100644 --- a/doc/classes/Area3D.xml +++ b/doc/classes/Area3D.xml @@ -28,14 +28,14 @@ </description> </method> <method name="get_overlapping_areas" qualifiers="const"> - <return type="Array"> + <return type="Area3D[]"> </return> <description> Returns a list of intersecting [Area3D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead. </description> </method> <method name="get_overlapping_bodies" qualifiers="const"> - <return type="Array"> + <return type="Node3D[]"> </return> <description> Returns a list of intersecting [PhysicsBody3D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead. diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 9e742ea581..b45716544a 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -22,6 +22,8 @@ m.mesh = arr_mesh [/codeblock] The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown. + See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation. + [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/arraymesh.html</link> @@ -56,7 +58,6 @@ 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 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 ARRAY_INDEX] if it is used. 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 order of the vertices. - Godot uses clockwise winding order for front faces of triangle primitive modes. </description> </method> <method name="clear_blend_shapes"> diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml index eab6505734..dbc3d3e21b 100644 --- a/doc/classes/AudioStreamPlayer.xml +++ b/doc/classes/AudioStreamPlayer.xml @@ -61,7 +61,7 @@ If the audio configuration has more than two speakers, this sets the target channels. See [enum MixTarget] constants. </member> <member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0"> - Changes the pitch and the tempo of the audio. + The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate. </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml index fdbef1b89e..844e2316ba 100644 --- a/doc/classes/AudioStreamPlayer2D.xml +++ b/doc/classes/AudioStreamPlayer2D.xml @@ -67,7 +67,7 @@ Maximum distance from which audio is still hearable. </member> <member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0"> - Changes the pitch and the tempo of the audio. + The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate. </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index 3eeb524e9c..bd90e3bd1a 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -91,7 +91,7 @@ Decides if audio should pause when source is outside of [member max_distance] range. </member> <member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0"> - Changes the pitch and the tempo of the audio. + The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate. </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml index 1f7554f978..7cc6a5613b 100644 --- a/doc/classes/BackBufferCopy.xml +++ b/doc/classes/BackBufferCopy.xml @@ -5,6 +5,7 @@ </brief_description> <description> Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use the [code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to access the buffer. + [b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), anchors and margins won't apply to child [Control]-derived nodes. This can be problematic when resizing the window. To avoid this, add [Control]-derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of adding them as children. </description> <tutorials> </tutorials> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 5bb94d2858..76abc31451 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -108,6 +108,15 @@ <member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel"> Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use. </member> + <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight"> + The color used by the backlight effect. Represents the light passing through an object. + </member> + <member name="backlight_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> + If [code]true[/code], the backlight effect is enabled. + </member> + <member name="backlight_texture" type="Texture2D" setter="set_texture" getter="get_texture"> + Texture used to control the backlight effect per-pixel. Added to [member backlight]. + </member> <member name="billboard_keep_scale" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], the shader will keep the scale set for the mesh. Otherwise the scale is lost when billboarding. Only applies when [member billboard_mode] is [constant BILLBOARD_ENABLED]. </member> @@ -296,6 +305,7 @@ Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use. </member> <member name="shading_mode" type="int" setter="set_shading_mode" getter="get_shading_mode" enum="BaseMaterial3D.ShadingMode" default="1"> + Sets whether the shading takes place per-pixel or per-vertex. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel. </member> <member name="shadow_to_opacity" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], enables the "shadow to opacity" render mode where lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR. @@ -307,6 +317,7 @@ If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges. </member> <member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag"> + If [code]true[/code], subsurface scattering will use a special mode optimized for the color and density of human skin. </member> <member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength"> The strength of the subsurface scattering effect. @@ -314,21 +325,24 @@ <member name="subsurf_scatter_texture" type="Texture2D" setter="set_texture" getter="get_texture"> Texture used to control the subsurface scattering strength. Stored in the red texture channel. Multiplied by [member subsurf_scatter_strength]. </member> + <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost"> + </member> + <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color"> + </member> + <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve"> + </member> + <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth"> + </member> + <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature"> + </member> + <member name="subsurf_scatter_transmittance_texture" type="Texture2D" setter="set_texture" getter="get_texture"> + </member> <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="BaseMaterial3D.TextureFilter" default="3"> Filter flags for the texture. See [enum TextureFilter] for options. </member> <member name="texture_repeat" type="bool" setter="set_flag" getter="get_flag" default="true"> Repeat flags for the texture. See [enum TextureFilter] for options. </member> - <member name="transmission" type="Color" setter="set_transmission" getter="get_transmission"> - The color used by the transmission effect. Represents the light passing through an object. - </member> - <member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> - If [code]true[/code], the transmission effect is enabled. - </member> - <member name="transmission_texture" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture used to control the transmission effect per-pixel. Added to [member transmission]. - </member> <member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0"> If [code]true[/code], transparency is enabled on the body. See also [member blend_mode]. </member> @@ -407,39 +421,47 @@ <constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10" enum="TextureParam"> Texture specifying per-pixel subsurface scattering. </constant> - <constant name="TEXTURE_TRANSMISSION" value="11" enum="TextureParam"> - Texture specifying per-pixel transmission color. + <constant name="TEXTURE_SUBSURFACE_TRANSMITTANCE" value="11" enum="TextureParam"> + Texture specifying per-pixel transmittance for subsurface scattering. + </constant> + <constant name="TEXTURE_BACKLIGHT" value="12" enum="TextureParam"> + Texture specifying per-pixel backlight color. </constant> - <constant name="TEXTURE_REFRACTION" value="12" enum="TextureParam"> + <constant name="TEXTURE_REFRACTION" value="13" enum="TextureParam"> Texture specifying per-pixel refraction strength. </constant> - <constant name="TEXTURE_DETAIL_MASK" value="13" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_MASK" value="14" enum="TextureParam"> Texture specifying per-pixel detail mask blending value. </constant> - <constant name="TEXTURE_DETAIL_ALBEDO" value="14" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_ALBEDO" value="15" enum="TextureParam"> Texture specifying per-pixel detail color. </constant> - <constant name="TEXTURE_DETAIL_NORMAL" value="15" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_NORMAL" value="16" enum="TextureParam"> Texture specifying per-pixel detail normal. </constant> - <constant name="TEXTURE_ORM" value="16" enum="TextureParam"> + <constant name="TEXTURE_ORM" value="17" enum="TextureParam"> + Texture holding ambient occlusion, roughness, and metallic. </constant> - <constant name="TEXTURE_MAX" value="17" enum="TextureParam"> + <constant name="TEXTURE_MAX" value="18" enum="TextureParam"> Represents the size of the [enum TextureParam] enum. </constant> <constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter"> The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter"> - The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style. + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter"> + The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. </constant> <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter"> + The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. </constant> <constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter"> Represents the size of the [enum TextureFilter] enum. @@ -457,8 +479,10 @@ The material will use the texture's alpha values for transparency. </constant> <constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency"> + The material will cut off all values below a threshold, the rest will remain opaque. </constant> <constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency"> + The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass. </constant> <constant name="TRANSPARENCY_MAX" value="4" enum="Transparency"> Represents the size of the [enum Transparency] enum. @@ -494,20 +518,24 @@ Constant for setting [member ao_enabled]. </constant> <constant name="FEATURE_HEIGHT_MAPPING" value="6" enum="Feature"> + Constant for setting [member heightmap_enabled]. </constant> - <constant name="FEATURE_SUBSURACE_SCATTERING" value="7" enum="Feature"> + <constant name="FEATURE_SUBSURFACE_SCATTERING" value="7" enum="Feature"> Constant for setting [member subsurf_scatter_enabled]. </constant> - <constant name="FEATURE_TRANSMISSION" value="8" enum="Feature"> - Constant for setting [member transmission_enabled]. + <constant name="FEATURE_SUBSURFACE_TRANSMITTANCE" value="8" enum="Feature"> + Constant for setting [member subsurf_scatter_transmittance_enabled]. + </constant> + <constant name="FEATURE_BACKLIGHT" value="9" enum="Feature"> + Constant for setting [member backlight_enabled]. </constant> - <constant name="FEATURE_REFRACTION" value="9" enum="Feature"> + <constant name="FEATURE_REFRACTION" value="10" enum="Feature"> Constant for setting [member refraction_enabled]. </constant> - <constant name="FEATURE_DETAIL" value="10" enum="Feature"> + <constant name="FEATURE_DETAIL" value="11" enum="Feature"> Constant for setting [member detail_enabled]. </constant> - <constant name="FEATURE_MAX" value="11" enum="Feature"> + <constant name="FEATURE_MAX" value="12" enum="Feature"> Represents the size of the [enum Feature] enum. </constant> <constant name="BLEND_MODE_MIX" value="0" enum="BlendMode"> @@ -589,11 +617,13 @@ Enables the shadow to opacity feature. </constant> <constant name="FLAG_USE_TEXTURE_REPEAT" value="16" enum="Flags"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="FLAG_INVERT_HEIGHTMAP" value="17" enum="Flags"> Invert values read from a depth texture to convert them to height values (heightmap). </constant> <constant name="FLAG_SUBSURFACE_MODE_SKIN" value="18" enum="Flags"> + Enables the skin mode for subsurface scattering which is used to improve the look of subsurface scattering when used for human skin. </constant> <constant name="FLAG_MAX" value="19" enum="Flags"> Represents the size of the [enum Flags] enum. diff --git a/doc/classes/CameraEffects.xml b/doc/classes/CameraEffects.xml index 23f0a1c7af..ea9ab85b80 100644 --- a/doc/classes/CameraEffects.xml +++ b/doc/classes/CameraEffects.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CameraEffects" inherits="Resource" version="4.0"> <brief_description> + Contains camera-specific effects such as depth of field and exposure override. </brief_description> <description> + Contains camera-specific effects such as depth of field and exposure override. + See also [Environment] for general 3D environment settings. </description> <tutorials> </tutorials> @@ -10,22 +13,31 @@ </methods> <members> <member name="dof_blur_amount" type="float" setter="set_dof_blur_amount" getter="get_dof_blur_amount" default="0.1"> + The amount of blur for both near and far depth-of-field effects. The amount of blur increases the radius of the blur effect, making the affected area blurrier. However, If the amount is too high, you might start to see lines appearing, especially when using a low quality blur. </member> <member name="dof_blur_far_distance" type="float" setter="set_dof_blur_far_distance" getter="get_dof_blur_far_distance" default="10.0"> + The distance from the camera where the far blur effect affects the rendering. </member> <member name="dof_blur_far_enabled" type="bool" setter="set_dof_blur_far_enabled" getter="is_dof_blur_far_enabled" default="false"> + If [code]true[/code], enables the depth-of-field far blur effect. This has a significant performance cost. Consider disabling it in scenes where there are no far away objects. </member> <member name="dof_blur_far_transition" type="float" setter="set_dof_blur_far_transition" getter="get_dof_blur_far_transition" default="5.0"> + The length of the transition between the no-blur area and far blur. </member> <member name="dof_blur_near_distance" type="float" setter="set_dof_blur_near_distance" getter="get_dof_blur_near_distance" default="2.0"> + Distance from the camera where the near blur effect affects the rendering. </member> <member name="dof_blur_near_enabled" type="bool" setter="set_dof_blur_near_enabled" getter="is_dof_blur_near_enabled" default="false"> + If [code]true[/code], enables the depth-of-field near blur effect. This has a significant performance cost. Consider disabling it in scenes where there are no nearby objects. </member> <member name="dof_blur_near_transition" type="float" setter="set_dof_blur_near_transition" getter="get_dof_blur_near_transition" default="1.0"> + The length of the transition between the near blur and no-blur area. </member> <member name="override_exposure" type="float" setter="set_override_exposure" getter="get_override_exposure" default="1.0"> + The exposure override value to use. Higher values will result in a brighter scene. Only effective if [member override_exposure_enable] is [code]true[/code]. </member> <member name="override_exposure_enable" type="bool" setter="set_override_exposure_enabled" getter="is_override_exposure_enabled" default="false"> + If [code]true[/code], overrides the manual or automatic exposure defined in the [Environment] with the value in [member override_exposure]. </member> </members> <constants> diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml new file mode 100644 index 0000000000..f7329d1537 --- /dev/null +++ b/doc/classes/Decal.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Decal" inherits="VisualInstance3D" version="4.0"> + <brief_description> + Node that projects a texture onto a [MeshInstance3D]. + </brief_description> + <description> + [Decal]s are used to project a texture onto a [Mesh] in the scene. Use Decals to add detail to a scene without affecting the underlying [Mesh]. They are often used to add weathering to building, add dirt or mud to the ground, or add variety to props. Decals can be moved at any time, making them suitable for things like blob shadows or laser sight dots. + They are made of an [AABB] and a group of [Texture2D]s specifying [Color], normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals are projected within their [AABB] so altering the orientation of the Decal affects the direction in which they are projected. By default, Decals are projected down (i.e. from positive Y to negative Y). + The [Texture2D]s associated with the Decal are automatically stored in a texture atlas which is used for drawing the decals so all decals can be drawn at once. Godot uses clustered decals, meaning they are stored in cluster data and drawn when the mesh is drawn, they are not drawn as a postprocessing effect after. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_texture" qualifiers="const"> + <return type="Texture2D"> + </return> + <argument index="0" name="type" type="int" enum="Decal.DecalTexture"> + </argument> + <description> + Returns the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. + For example, instead of [code]albedo_tex = $Decal.get_texture(Decal.TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/code]. + One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: + [codeblock] + for i in Decal.TEXTURE_MAX: + $NewDecal.set_texture(i, $OldDecal.get_texture(i)) + [/codeblock] + </description> + </method> + <method name="set_texture"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Decal.DecalTexture"> + </argument> + <argument index="1" name="texture" type="Texture2D"> + </argument> + <description> + Sets the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. + For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code]. + One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: + [codeblock] + for i in Decal.TEXTURE_MAX: + $NewDecal.set_texture(i, $OldDecal.get_texture(i)) + [/codeblock] + </description> + </method> + </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. + </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 an 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> + <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. + </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> + <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. + </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]. + </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. + </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. + </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. + </member> + <member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] with the emission [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. + </member> + <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] with the per-pixel normalmap for the decal. Use this to add extra detail to decals. + </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. + </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]. + </member> + </members> + <constants> + <constant name="TEXTURE_ALBEDO" value="0" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_albedo]. + </constant> + <constant name="TEXTURE_NORMAL" value="1" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_normal]. + </constant> + <constant name="TEXTURE_ORM" value="2" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_orm]. + </constant> + <constant name="TEXTURE_EMISSION" value="3" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_emission]. + </constant> + <constant name="TEXTURE_MAX" value="4" enum="DecalTexture"> + Max size of [enum DecalTexture] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 7bd01d6781..e982e00d6d 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -11,7 +11,7 @@ [codeblock] var my_dir = {} # Creates an empty dictionary. var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} - var my_dir = { + var another_dir = { key1: value1, key2: value2, key3: value3, @@ -34,7 +34,7 @@ To add a key to an existing dictionary, access it like an existing key and assign to it: [codeblock] var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} - var points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. + points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. [/codeblock] Finally, dictionaries can contain different types of keys and values in the same dictionary: [codeblock] diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml index a5d476f5c8..6c88dcf42e 100644 --- a/doc/classes/DirectionalLight3D.xml +++ b/doc/classes/DirectionalLight3D.xml @@ -12,9 +12,6 @@ <methods> </methods> <members> - <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" default="0.25"> - Amount of extra bias for shadow splits that are far away. If self-shadowing occurs only on the splits far away, increasing this value can fix them. - </member> <member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" default="false"> If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits. </member> @@ -22,6 +19,7 @@ Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange]. </member> <member name="directional_shadow_fade_start" type="float" setter="set_param" getter="get_param" default="0.8"> + Proportion of [member directional_shadow_max_distance] at which point the shadow starts to fade. At [member directional_shadow_max_distance] the shadow will disappear. </member> <member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="100.0"> The maximum distance for shadow splits. @@ -29,8 +27,8 @@ <member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="DirectionalLight3D.ShadowMode" default="2"> The light's shadow rendering algorithm. See [enum ShadowMode]. </member> - <member name="directional_shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="0.8"> - Can be used to fix special cases of self shadowing when objects are perpendicular to the light. + <member name="directional_shadow_pancake_size" type="float" setter="set_param" getter="get_param" default="20.0"> + 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. </member> <member name="directional_shadow_split_1" type="float" setter="set_param" getter="get_param" default="0.1"> The distance from camera to shadow split 1. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code]. @@ -41,7 +39,6 @@ <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" /> </members> <constants> <constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode"> diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml index 11610fa523..0864c3ba36 100644 --- a/doc/classes/DynamicFont.xml +++ b/doc/classes/DynamicFont.xml @@ -12,7 +12,7 @@ dynamic_font.size = 64 $"Label".set("custom_fonts/font", dynamic_font) [/codeblock] - [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font. + [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml index 53db8dd293..eb03d3010f 100644 --- a/doc/classes/EditorFeatureProfile.xml +++ b/doc/classes/EditorFeatureProfile.xml @@ -72,7 +72,7 @@ <argument index="0" name="path" type="String"> </argument> <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] button. </description> </method> <method name="set_disable_class"> diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml index 30e1de1f5e..9bb51af2d0 100644 --- a/doc/classes/EditorFileSystem.xml +++ b/doc/classes/EditorFileSystem.xml @@ -5,6 +5,7 @@ </brief_description> <description> This object holds information of all resources in the filesystem, their types, etc. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_filesystem]. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml index 61d240c1dc..2f62fe9e40 100644 --- a/doc/classes/EditorInspector.xml +++ b/doc/classes/EditorInspector.xml @@ -5,6 +5,7 @@ </brief_description> <description> The editor inspector is by default located on the right-hand side of the editor. It's used to edit the properties of the selected node. For example, you can select a node such as the Sprite2D then edit its transform through the inspector tool. The editor inspector is an essential tool in the game development workflow. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_inspector]. </description> <tutorials> </tutorials> @@ -26,6 +27,12 @@ <description> </description> </signal> + <signal name="property_deleted"> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </signal> <signal name="property_edited"> <argument index="0" name="property" type="String"> </argument> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index 5e76f90fc4..499c3b8271 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -5,6 +5,7 @@ </brief_description> <description> EditorInterface gives you control over Godot editor's window. It allows customizing the window, saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects, and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], [ScriptEditor], the editor viewport, and information about scenes. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorPlugin.get_editor_interface]. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 3216541b20..4da3b58b94 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -78,6 +78,8 @@ <member name="checked" type="bool" setter="set_checked" getter="is_checked" default="false"> Used by the inspector, when the property is checked. </member> + <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false"> + </member> <member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false"> Used by the inspector, when the property must draw with error color. </member> @@ -128,6 +130,12 @@ Emitted when a property was checked. Used internally. </description> </signal> + <signal name="property_deleted"> + <argument index="0" name="property" type="StringName"> + </argument> + <description> + </description> + </signal> <signal name="property_keyed"> <argument index="0" name="property" type="StringName"> </argument> diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml index aac75c5c8e..0c1d969518 100644 --- a/doc/classes/EditorResourcePreview.xml +++ b/doc/classes/EditorResourcePreview.xml @@ -5,6 +5,7 @@ </brief_description> <description> This object is used to generate previews for resources of files. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_previewer]. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml index caafd3c15f..1ff9744b70 100644 --- a/doc/classes/EditorSelection.xml +++ b/doc/classes/EditorSelection.xml @@ -5,6 +5,7 @@ </brief_description> <description> This object manages the SceneTree selection in the editor. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_selection]. </description> <tutorials> </tutorials> @@ -26,7 +27,7 @@ </description> </method> <method name="get_selected_nodes"> - <return type="Array"> + <return type="Node[]"> </return> <description> Gets the list of selected nodes. diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 73ef807c5f..19921ff5c8 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -11,6 +11,7 @@ settings.get(prop) list_of_settings = settings.get_property_list() [/codeblock] + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings]. </description> <tutorials> </tutorials> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 6f55bfc229..3642d92771 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -265,18 +265,25 @@ Represents the size of the [enum BGMode] enum. </constant> <constant name="AMBIENT_SOURCE_BG" value="0" enum="AmbientSource"> + Gather ambient light from whichever source is specified as the background. </constant> <constant name="AMBIENT_SOURCE_DISABLED" value="1" enum="AmbientSource"> + Disable ambient light. </constant> <constant name="AMBIENT_SOURCE_COLOR" value="2" enum="AmbientSource"> + Specify a specific [Color] for ambient light. </constant> <constant name="AMBIENT_SOURCE_SKY" value="3" enum="AmbientSource"> + Gather ambient light from the [Sky] regardless of what the background is. </constant> <constant name="REFLECTION_SOURCE_BG" value="0" enum="ReflectionSource"> + Use the background for reflections. </constant> <constant name="REFLECTION_SOURCE_DISABLED" value="1" enum="ReflectionSource"> + Disable reflections. </constant> <constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource"> + Use the [Sky] for reflections regardless of what the background is. </constant> <constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode"> Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. @@ -291,6 +298,7 @@ Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness. </constant> <constant name="GLOW_BLEND_MODE_MIX" value="4" enum="GlowBlendMode"> + Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper"> Linear tonemapper operator. Reads the linear data and passes it on unmodified. @@ -314,7 +322,7 @@ 2×2 blur for the screen-space ambient occlusion effect. </constant> <constant name="SSAO_BLUR_3x3" value="3" enum="SSAOBlur"> - 3×3 blur for the screen-space ambient occlusion effect (slowest). + 3×3 blur for the screen-space ambient occlusion effect. Increases the radius of the blur for a smoother look, but can result in checkerboard-like artifacts. </constant> </constants> </class> diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index 7df5f0ea50..518a172973 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -18,6 +18,14 @@ Returns the [enum GeometryInstance3D.Flags] that have been set for this object. </description> </method> + <method name="get_shader_instance_uniform" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="uniform" type="StringName"> + </argument> + <description> + </description> + </method> <method name="set_custom_aabb"> <return type="void"> </return> @@ -38,6 +46,16 @@ Sets the [enum GeometryInstance3D.Flags] specified. See [enum GeometryInstance3D.Flags] for options. </description> </method> + <method name="set_shader_instance_uniform"> + <return type="void"> + </return> + <argument index="0" name="uniform" type="StringName"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" enum="GeometryInstance3D.ShadowCastingSetting" default="1"> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index c41ffd4bff..750ac8085c 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -273,6 +273,12 @@ Emitted when a GraphNode is selected. </description> </signal> + <signal name="node_unselected"> + <argument index="0" name="node" type="Node"> + </argument> + <description> + </description> + </signal> <signal name="paste_nodes_request"> <description> Emitted when the user presses [code]Ctrl + V[/code]. diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml index 2738958058..afe9d10d2e 100644 --- a/doc/classes/HSlider.xml +++ b/doc/classes/HSlider.xml @@ -19,6 +19,8 @@ <theme_item name="grabber_area" type="StyleBox"> The background of the area to the left of the grabber. </theme_item> + <theme_item name="grabber_area_highlight" type="StyleBox"> + </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> The texture for the grabber when it's disabled. </theme_item> diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml deleted file mode 100644 index 79cdf2ce08..0000000000 --- a/doc/classes/IP_Unix.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="IP_Unix" inherits="IP" version="4.0"> - <brief_description> - UNIX IP support. See [IP]. - </brief_description> - <description> - UNIX-specific implementation of IP support functions. See [IP]. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/ImmediateGeometry3D.xml b/doc/classes/ImmediateGeometry3D.xml index 1c0831c922..d2d663847f 100644 --- a/doc/classes/ImmediateGeometry3D.xml +++ b/doc/classes/ImmediateGeometry3D.xml @@ -5,6 +5,9 @@ </brief_description> <description> Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x. + See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural geometry generation. + [b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh data that change every frame. It will be slow when handling large amounts of mesh data. If mesh data doesn't change often, use [ArrayMesh], [MeshDataTool] or [SurfaceTool] instead. + [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. </description> <tutorials> </tutorials> diff --git a/doc/classes/InputFilter.xml b/doc/classes/Input.xml index 54184ae8a3..0f212e7498 100644 --- a/doc/classes/InputFilter.xml +++ b/doc/classes/Input.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputFilter" inherits="Object" version="4.0"> +<class name="Input" inherits="Object" version="4.0"> <brief_description> A singleton that deals with inputs. </brief_description> @@ -68,7 +68,7 @@ </description> </method> <method name="get_current_cursor_shape" qualifiers="const"> - <return type="int" enum="InputFilter.CursorShape"> + <return type="int" enum="Input.CursorShape"> </return> <description> Returns the currently assigned cursor shape (see [enum CursorShape]). @@ -193,7 +193,7 @@ </description> </method> <method name="get_mouse_mode" qualifiers="const"> - <return type="int" enum="InputFilter.MouseMode"> + <return type="int" enum="Input.MouseMode"> </return> <description> Returns the mouse mode. See the constants for more information. @@ -277,7 +277,7 @@ <argument index="3" name="guid" type="String"> </argument> <description> - Notifies the [InputFilter] singleton that a connection has changed, to update the state for the [code]device[/code] index. + Notifies the [Input] singleton that a connection has changed, to update the state for the [code]device[/code] index. This is used internally and should not have to be called from user scripts. See [signal joy_connection_changed] for the signal emitted when this is triggered internally. </description> </method> @@ -293,7 +293,7 @@ var a = InputEventAction.new() a.action = "ui_cancel" a.pressed = true - InputFilter.parse_input_event(a) + Input.parse_input_event(a) [/codeblock] </description> </method> @@ -311,7 +311,7 @@ </return> <argument index="0" name="image" type="Resource"> </argument> - <argument index="1" name="shape" type="int" enum="InputFilter.CursorShape" default="0"> + <argument index="1" name="shape" type="int" enum="Input.CursorShape" default="0"> </argument> <argument index="2" name="hotspot" type="Vector2" default="Vector2( 0, 0 )"> </argument> @@ -326,7 +326,7 @@ <method name="set_default_cursor_shape"> <return type="void"> </return> - <argument index="0" name="shape" type="int" enum="InputFilter.CursorShape" default="0"> + <argument index="0" name="shape" type="int" enum="Input.CursorShape" default="0"> </argument> <description> Sets the default cursor shape to be used in the viewport instead of [constant CURSOR_ARROW]. @@ -337,7 +337,7 @@ <method name="set_mouse_mode"> <return type="void"> </return> - <argument index="0" name="mode" type="int" enum="InputFilter.MouseMode"> + <argument index="0" name="mode" type="int" enum="Input.MouseMode"> </argument> <description> Sets the mouse mode. See the constants for more information. diff --git a/doc/classes/MonoGCHandle.xml b/doc/classes/JNISingleton.xml index 1e33dd1359..84ab1a49c1 100644 --- a/doc/classes/MonoGCHandle.xml +++ b/doc/classes/JNISingleton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MonoGCHandle" inherits="Reference" version="4.0"> +<class name="JNISingleton" inherits="Object" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 623b2a2bb0..cb21db2d00 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -56,13 +56,16 @@ <member name="light_negative" type="bool" setter="set_negative" getter="is_negative" default="false"> If [code]true[/code], the light's effect is reversed, darkening areas and casting bright shadows. </member> + <member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector"> + [Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained glass. + </member> <member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0"> The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s. </member> <member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5"> The intensity of the specular blob in objects affected by the light. At [code]0[/code] the light becomes a pure diffuse light. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.15"> + <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.02"> Used to adjust shadow appearance. Too small a value results in self-shadowing, while too large a value causes shadows to separate from casters. Adjust as needed. </member> <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0"> @@ -71,15 +74,17 @@ <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 1 )"> The color of shadows cast by this light. </member> - <member name="shadow_contact" type="float" setter="set_param" getter="get_param" default="0.0"> - Attempts to reduce [member shadow_bias] gap. - </member> <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast shadows. </member> + <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 objects normal. This can be used reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. + </member> <member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false"> 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> + <member name="shadow_transmittance_bias" type="float" setter="set_param" getter="get_param" default="0.05"> + </member> </members> <constants> <constant name="PARAM_ENERGY" value="0" enum="Param"> @@ -94,18 +99,18 @@ <constant name="PARAM_RANGE" value="3" enum="Param"> Constant for accessing [member OmniLight3D.omni_range] or [member SpotLight3D.spot_range]. </constant> - <constant name="PARAM_ATTENUATION" value="4" enum="Param"> + <constant name="PARAM_SIZE" value="4" enum="Param"> + Constant for accessing [member light_size]. + </constant> + <constant name="PARAM_ATTENUATION" value="5" enum="Param"> Constant for accessing [member OmniLight3D.omni_attenuation] or [member SpotLight3D.spot_attenuation]. </constant> - <constant name="PARAM_SPOT_ANGLE" value="5" enum="Param"> + <constant name="PARAM_SPOT_ANGLE" value="6" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle]. </constant> - <constant name="PARAM_SPOT_ATTENUATION" value="6" enum="Param"> + <constant name="PARAM_SPOT_ATTENUATION" value="7" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle_attenuation]. </constant> - <constant name="PARAM_CONTACT_SHADOW_SIZE" value="7" enum="Param"> - Constant for accessing [member shadow_contact]. - </constant> <constant name="PARAM_SHADOW_MAX_DISTANCE" value="8" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_max_distance]. </constant> @@ -119,17 +124,24 @@ Constant for accessing [member DirectionalLight3D.directional_shadow_split_3]. </constant> <constant name="PARAM_SHADOW_FADE_START" value="12" enum="Param"> + Constant for accessing [member DirectionalLight3D.directional_shadow_fade_start]. </constant> <constant name="PARAM_SHADOW_NORMAL_BIAS" value="13" enum="Param"> - Constant for accessing [member DirectionalLight3D.directional_shadow_normal_bias]. + Constant for accessing [member shadow_normal_bias]. </constant> <constant name="PARAM_SHADOW_BIAS" value="14" enum="Param"> Constant for accessing [member shadow_bias]. </constant> - <constant name="PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="Param"> - Constant for accessing [member DirectionalLight3D.directional_shadow_bias_split_scale]. + <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 for accessing [member shadow_blur]. + </constant> + <constant name="PARAM_TRANSMITTANCE_BIAS" value="17" enum="Param"> + Constant for accessing [member shadow_transmittance_bias]. </constant> - <constant name="PARAM_MAX" value="16" enum="Param"> + <constant name="PARAM_MAX" value="18" enum="Param"> Represents the size of the [enum Param] enum. </constant> <constant name="BAKE_DISABLED" value="0" enum="BakeMode"> diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml index 68cec3e624..cfd23b28bd 100644 --- a/doc/classes/Line2D.xml +++ b/doc/classes/Line2D.xml @@ -72,7 +72,7 @@ <member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" enum="Line2D.LineCapMode" default="0"> Controls the style of the line's first point. Use [enum LineCapMode] constants. </member> - <member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color( 0.4, 0.5, 1, 1 )"> + <member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color( 1, 1, 1, 1 )"> The line's color. Will not be used if a gradient is set. </member> <member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" enum="Line2D.LineCapMode" default="0"> diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml index 81ff5969e3..dcc3bbf2a6 100644 --- a/doc/classes/MeshDataTool.xml +++ b/doc/classes/MeshDataTool.xml @@ -17,6 +17,8 @@ mesh.surface_remove(0) mdt.commit_to_surface(mesh) [/codeblock] + See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural geometry generation. + [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. </description> <tutorials> </tutorials> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 8c588f0373..1c745de7f0 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -221,7 +221,7 @@ </description> </method> <method name="get_children" qualifiers="const"> - <return type="Array"> + <return type="Node[]"> </return> <description> Returns an array of references to node's children. diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index e422545b7b..2d70dea012 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -9,23 +9,25 @@ [b]Note:[/b] The node doesn't need to own itself. [b]Example of saving a node with different owners:[/b] The following example creates 3 objects: [code]Node2D[/code] ([code]node[/code]), [code]RigidBody2D[/code] ([code]rigid[/code]) and [code]CollisionObject2D[/code] ([code]collision[/code]). [code]collision[/code] is a child of [code]rigid[/code] which is a child of [code]node[/code]. Only [code]rigid[/code] is owned by [code]node[/code] and [code]pack[/code] will therefore only save those two nodes, but not [code]collision[/code]. [codeblock] - # Create the objects + # Create the objects. var node = Node2D.new() var rigid = RigidBody2D.new() var collision = CollisionShape2D.new() - # Create the object hierarchy + # Create the object hierarchy. rigid.add_child(collision) node.add_child(rigid) - # Change owner of rigid, but not of collision + # Change owner of `rigid`, but not of `collision`. rigid.owner = node var scene = PackedScene.new() - # Only node and rigid are now packed + # Only `node` and `rigid` are now packed. var result = scene.pack(node) if result == OK: - ResourceSaver.save("res://path/name.scn", scene) # Or "user://..." + var error = ResourceSaver.save("res://path/name.scn", scene) # Or "user://..." + if error != OK: + push_error("An error occurred while saving the scene to disk.") [/codeblock] </description> <tutorials> diff --git a/doc/classes/Path2D.xml b/doc/classes/Path2D.xml index ab266a2f73..57e2091268 100644 --- a/doc/classes/Path2D.xml +++ b/doc/classes/Path2D.xml @@ -15,7 +15,6 @@ <member name="curve" type="Curve2D" setter="set_curve" getter="get_curve"> A [Curve2D] describing the path. </member> - <member name="self_modulate" type="Color" setter="set_self_modulate" getter="get_self_modulate" override="true" default="Color( 0.5, 0.6, 1, 0.7 )" /> </members> <constants> </constants> diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index 75f1f3eab4..58930aae37 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -25,6 +25,14 @@ <description> </description> </method> + <method name="get_axis_lock" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis"> + </argument> + <description> + </description> + </method> <method name="get_bone_id" qualifiers="const"> <return type="int"> </return> @@ -43,6 +51,16 @@ <description> </description> </method> + <method name="set_axis_lock"> + <return type="void"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis"> + </argument> + <argument index="1" name="lock" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="-1.0"> @@ -84,7 +102,7 @@ <member name="joint_offset" type="Transform" setter="set_joint_offset" getter="get_joint_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> Sets the joint's transform. </member> - <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation" default="Vector3( 0, 0, 0 )"> + <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation"> Sets the joint's rotation in radians. </member> <member name="joint_rotation_degrees" type="Vector3" setter="set_joint_rotation_degrees" getter="get_joint_rotation_degrees" default="Vector3( 0, 0, 0 )"> diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml index 28d6ce7048..6afbd1ee8e 100644 --- a/doc/classes/PhysicsBody2D.xml +++ b/doc/classes/PhysicsBody2D.xml @@ -20,7 +20,7 @@ </description> </method> <method name="get_collision_exceptions"> - <return type="Array"> + <return type="PhysicsBody2D[]"> </return> <description> Returns an array of nodes that were added as collision exceptions for this body. diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml index f0ba2a7f5f..2301a07a5c 100644 --- a/doc/classes/PhysicsBody3D.xml +++ b/doc/classes/PhysicsBody3D.xml @@ -20,7 +20,7 @@ </description> </method> <method name="get_collision_exceptions"> - <return type="Array"> + <return type="PhysicsBody3D[]"> </return> <description> Returns an array of nodes that were added as collision exceptions for this body. diff --git a/doc/classes/PhysicsDirectBodyState2DSW.xml b/doc/classes/PhysicsDirectBodyState2DSW.xml deleted file mode 100644 index 94fc4213b7..0000000000 --- a/doc/classes/PhysicsDirectBodyState2DSW.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsDirectBodyState2DSW" inherits="PhysicsDirectBodyState2D" version="4.0"> - <brief_description> - Software implementation of [PhysicsDirectBodyState2D]. - </brief_description> - <description> - Software implementation of [PhysicsDirectBodyState2D]. This object exposes no new methods or properties and should not be used, as [PhysicsDirectBodyState2D] selects the best implementation available. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/PhysicsServer2DSW.xml b/doc/classes/PhysicsServer2DSW.xml deleted file mode 100644 index dac5e360f0..0000000000 --- a/doc/classes/PhysicsServer2DSW.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsServer2DSW" inherits="PhysicsServer2D" version="4.0"> - <brief_description> - Software implementation of [PhysicsServer2D]. - </brief_description> - <description> - This class exposes no new methods or properties and should not be used, as [PhysicsServer2D] automatically selects the best implementation available. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 66bf8c8286..9e917fb4dd 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -92,10 +92,8 @@ </argument> <argument index="1" name="replace_files" type="bool" default="true"> </argument> - <argument index="2" name="destination" type="String" default=""> - </argument> <description> - Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]) at the [code]destination[/code] path, if given. Returns [code]true[/code] on success. + Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success. [b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code]. </description> </method> @@ -262,19 +260,19 @@ Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing. </member> <member name="compression/formats/gzip/compression_level" type="int" setter="" getter="" default="-1"> - Default compression level for gzip. Affects compressed scenes and resources. + The default compression level for gzip. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. [code]-1[/code] uses the default gzip compression level, which is identical to [code]6[/code] but could change in the future due to underlying zlib updates. </member> <member name="compression/formats/zlib/compression_level" type="int" setter="" getter="" default="-1"> - Default compression level for Zlib. Affects compressed scenes and resources. + The default compression level for Zlib. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. [code]-1[/code] uses the default gzip compression level, which is identical to [code]6[/code] but could change in the future due to underlying zlib updates. </member> <member name="compression/formats/zstd/compression_level" type="int" setter="" getter="" default="3"> - Default compression level for Zstandard. Affects compressed scenes and resources. + The default compression level for Zstandard. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. </member> <member name="compression/formats/zstd/long_distance_matching" type="bool" setter="" getter="" default="false"> - Enables long-distance matching in Zstandard. + Enables [url=https://github.com/facebook/zstd/releases/tag/v1.3.2]long-distance matching[/url] in Zstandard. </member> <member name="compression/formats/zstd/window_log_size" type="int" setter="" getter="" default="27"> - Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. + Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. Higher values can result in better compression, but will require more memory when compressing and decompressing. </member> <member name="debug/gdscript/completion/autocomplete_setters_and_getters" type="bool" setter="" getter="" default="false"> If [code]true[/code], displays getters and setters in autocompletion results in the script editor. This setting is meant to be used when porting old projects (Godot 2), as using member variables is the preferred style from Godot 3 onwards. @@ -974,6 +972,8 @@ <member name="rendering/environment/default_environment" type="String" setter="" getter="" default=""""> [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here. </member> + <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536"> + </member> <member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000"> Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves. </member> @@ -984,6 +984,15 @@ <member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false"> If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles. </member> + <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> + Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. + </member> + <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> + Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute. + </member> + <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> + If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples. + </member> <member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default=""PowerVR,Mali,Adreno,Apple""> Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this. </member> @@ -1000,7 +1009,7 @@ Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. </member> <member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> - Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. + Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default=""Vulkan""> The video driver to use ("GLES2" or "Vulkan"). @@ -1008,32 +1017,17 @@ [b]FIXME:[/b] No longer valid after DisplayServer split: In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time. </member> - <member name="rendering/quality/filters/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> - </member> - <member name="rendering/quality/filters/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> - </member> - <member name="rendering/quality/filters/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> - </member> - <member name="rendering/quality/filters/max_anisotropy" type="int" setter="" getter="" default="4"> - </member> - <member name="rendering/quality/filters/msaa" type="int" setter="" getter="" default="0"> - Sets the number of MSAA samples to use. 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. - [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend. - </member> - <member name="rendering/quality/filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0"> - </member> - <member name="rendering/quality/filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0"> - </member> - <member name="rendering/quality/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. - </member> <member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false"> + If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction. </member> <member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1"> + Sets the number of cone samples taken when rendering objects affected by [GIProbe]s. </member> <member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1"> + Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth. </member> <member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2"> Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment]. @@ -1068,7 +1062,22 @@ <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> + <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0"> + Sets the number of MSAA samples to use. 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. + [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend. + </member> + <member name="rendering/quality/screen_filters/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. + Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter]. + </member> + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0"> + Enables the screen-space roughness limiter which increases material roughness in areas with a high normal frequency (i.e. when normals change a lot from pixel to pixel). This helps to reduce the amount of specular aliasing in a scene. Specular aliasing looks like random bright pixels that occur in reflections. + </member> + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0"> + Curves the amount of the roughness limited effect. A higher value limits the effect to very sharply curved surfaces, while a lower threshold extends the effect to smoother surfaces. + </member> <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> + Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. </member> <member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model. @@ -1113,14 +1122,26 @@ Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false"> + If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details. </member> <member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="1"> + Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01"> + Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1"> + Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05"> + Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light. + </member> + <member name="rendering/quality/texture_filters/max_anisotropy" type="int" setter="" getter="" default="4"> + Sets the maximum number of samples to take when using anisotropic filtering on textures. A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. + Only power of two values are valid ([code]1[/code], [code]2[/code], [code]4[/code], [code]8[/code], [code]16[/code]). A value of [code]1[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. + </member> + <member name="rendering/quality/texture_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. </member> <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1"> Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. @@ -1148,6 +1169,9 @@ </member> <member name="rendering/vulkan/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64"> </member> + <member name="world/2d/cell_size" type="int" setter="" getter="" default="100"> + Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses. + </member> </members> <constants> </constants> diff --git a/doc/classes/RDAttachmentFormat.xml b/doc/classes/RDAttachmentFormat.xml new file mode 100644 index 0000000000..4ee7b9b28e --- /dev/null +++ b/doc/classes/RDAttachmentFormat.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDAttachmentFormat" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="36"> + </member> + <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0"> + </member> + <member name="usage_flags" type="int" setter="set_usage_flags" getter="get_usage_flags" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineColorBlendState.xml b/doc/classes/RDPipelineColorBlendState.xml new file mode 100644 index 0000000000..adc6f1f6a3 --- /dev/null +++ b/doc/classes/RDPipelineColorBlendState.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineColorBlendState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="attachments" type="RDPipelineColorBlendStateAttachment[]" setter="set_attachments" getter="get_attachments" default="[ ]"> + </member> + <member name="blend_constant" type="Color" setter="set_blend_constant" getter="get_blend_constant" default="Color( 0, 0, 0, 1 )"> + </member> + <member name="enable_logic_op" type="bool" setter="set_enable_logic_op" getter="get_enable_logic_op" default="false"> + </member> + <member name="logic_op" type="int" setter="set_logic_op" getter="get_logic_op" enum="RenderingDevice.LogicOperation" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineColorBlendStateAttachment.xml b/doc/classes/RDPipelineColorBlendStateAttachment.xml new file mode 100644 index 0000000000..7f118b5f0b --- /dev/null +++ b/doc/classes/RDPipelineColorBlendStateAttachment.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineColorBlendStateAttachment" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="set_as_mix"> + <return type="void"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="alpha_blend_op" type="int" setter="set_alpha_blend_op" getter="get_alpha_blend_op" enum="RenderingDevice.BlendOperation" default="0"> + </member> + <member name="color_blend_op" type="int" setter="set_color_blend_op" getter="get_color_blend_op" enum="RenderingDevice.BlendOperation" default="0"> + </member> + <member name="dst_alpha_blend_factor" type="int" setter="set_dst_alpha_blend_factor" getter="get_dst_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="dst_color_blend_factor" type="int" setter="set_dst_color_blend_factor" getter="get_dst_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="enable_blend" type="bool" setter="set_enable_blend" getter="get_enable_blend" default="false"> + </member> + <member name="src_alpha_blend_factor" type="int" setter="set_src_alpha_blend_factor" getter="get_src_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="src_color_blend_factor" type="int" setter="set_src_color_blend_factor" getter="get_src_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="write_a" type="bool" setter="set_write_a" getter="get_write_a" default="true"> + </member> + <member name="write_b" type="bool" setter="set_write_b" getter="get_write_b" default="true"> + </member> + <member name="write_g" type="bool" setter="set_write_g" getter="get_write_g" default="true"> + </member> + <member name="write_r" type="bool" setter="set_write_r" getter="get_write_r" default="true"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineDepthStencilState.xml b/doc/classes/RDPipelineDepthStencilState.xml new file mode 100644 index 0000000000..562ff52819 --- /dev/null +++ b/doc/classes/RDPipelineDepthStencilState.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineDepthStencilState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="back_op_compare" type="int" setter="set_back_op_compare" getter="get_back_op_compare" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="back_op_compare_mask" type="int" setter="set_back_op_compare_mask" getter="get_back_op_compare_mask" default="0"> + </member> + <member name="back_op_depth_fail" type="int" setter="set_back_op_depth_fail" getter="get_back_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_fail" type="int" setter="set_back_op_fail" getter="get_back_op_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_pass" type="int" setter="set_back_op_pass" getter="get_back_op_pass" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_reference" type="int" setter="set_back_op_reference" getter="get_back_op_reference" default="0"> + </member> + <member name="back_op_write_mask" type="int" setter="set_back_op_write_mask" getter="get_back_op_write_mask" default="0"> + </member> + <member name="depth_compare_operator" type="int" setter="set_depth_compare_operator" getter="get_depth_compare_operator" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="depth_range_max" type="float" setter="set_depth_range_max" getter="get_depth_range_max" default="0.0"> + </member> + <member name="depth_range_min" type="float" setter="set_depth_range_min" getter="get_depth_range_min" default="0.0"> + </member> + <member name="enable_depth_range" type="bool" setter="set_enable_depth_range" getter="get_enable_depth_range" default="false"> + </member> + <member name="enable_depth_test" type="bool" setter="set_enable_depth_test" getter="get_enable_depth_test" default="false"> + </member> + <member name="enable_depth_write" type="bool" setter="set_enable_depth_write" getter="get_enable_depth_write" default="false"> + </member> + <member name="enable_stencil" type="bool" setter="set_enable_stencil" getter="get_enable_stencil" default="false"> + </member> + <member name="front_op_compare" type="int" setter="set_front_op_compare" getter="get_front_op_compare" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="front_op_compare_mask" type="int" setter="set_front_op_compare_mask" getter="get_front_op_compare_mask" default="0"> + </member> + <member name="front_op_depth_fail" type="int" setter="set_front_op_depth_fail" getter="get_front_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_fail" type="int" setter="set_front_op_fail" getter="get_front_op_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_pass" type="int" setter="set_front_op_pass" getter="get_front_op_pass" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_reference" type="int" setter="set_front_op_reference" getter="get_front_op_reference" default="0"> + </member> + <member name="front_op_write_mask" type="int" setter="set_front_op_write_mask" getter="get_front_op_write_mask" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineMultisampleState.xml b/doc/classes/RDPipelineMultisampleState.xml new file mode 100644 index 0000000000..4658c7d9ba --- /dev/null +++ b/doc/classes/RDPipelineMultisampleState.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineMultisampleState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="enable_alpha_to_coverage" type="bool" setter="set_enable_alpha_to_coverage" getter="get_enable_alpha_to_coverage" default="false"> + </member> + <member name="enable_alpha_to_one" type="bool" setter="set_enable_alpha_to_one" getter="get_enable_alpha_to_one" default="false"> + </member> + <member name="enable_sample_shading" type="bool" setter="set_enable_sample_shading" getter="get_enable_sample_shading" default="false"> + </member> + <member name="min_sample_shading" type="float" setter="set_min_sample_shading" getter="get_min_sample_shading" default="0.0"> + </member> + <member name="sample_count" type="int" setter="set_sample_count" getter="get_sample_count" enum="RenderingDevice.TextureSamples" default="0"> + </member> + <member name="sample_masks" type="int[]" setter="set_sample_masks" getter="get_sample_masks" default="[ ]"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineRasterizationState.xml b/doc/classes/RDPipelineRasterizationState.xml new file mode 100644 index 0000000000..5064dd6deb --- /dev/null +++ b/doc/classes/RDPipelineRasterizationState.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineRasterizationState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="RenderingDevice.PolygonCullMode" default="0"> + </member> + <member name="depth_bias_clamp" type="float" setter="set_depth_bias_clamp" getter="get_depth_bias_clamp" default="0.0"> + </member> + <member name="depth_bias_constant_factor" type="float" setter="set_depth_bias_constant_factor" getter="get_depth_bias_constant_factor" default="0.0"> + </member> + <member name="depth_bias_enable" type="bool" setter="set_depth_bias_enable" getter="get_depth_bias_enable" default="false"> + </member> + <member name="depth_bias_slope_factor" type="float" setter="set_depth_bias_slope_factor" getter="get_depth_bias_slope_factor" default="0.0"> + </member> + <member name="discard_primitives" type="bool" setter="set_discard_primitives" getter="get_discard_primitives" default="false"> + </member> + <member name="enable_depth_clamp" type="bool" setter="set_enable_depth_clamp" getter="get_enable_depth_clamp" default="false"> + </member> + <member name="front_face" type="int" setter="set_front_face" getter="get_front_face" enum="RenderingDevice.PolygonFrontFace" default="0"> + </member> + <member name="line_width" type="float" setter="set_line_width" getter="get_line_width" default="1.0"> + </member> + <member name="patch_control_points" type="int" setter="set_patch_control_points" getter="get_patch_control_points" default="1"> + </member> + <member name="wireframe" type="bool" setter="set_wireframe" getter="get_wireframe" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDSamplerState.xml b/doc/classes/RDSamplerState.xml new file mode 100644 index 0000000000..ab31960b7c --- /dev/null +++ b/doc/classes/RDSamplerState.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDSamplerState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="anisotropy_max" type="float" setter="set_anisotropy_max" getter="get_anisotropy_max" default="1.0"> + </member> + <member name="border_color" type="int" setter="set_border_color" getter="get_border_color" enum="RenderingDevice.SamplerBorderColor" default="2"> + </member> + <member name="compare_op" type="int" setter="set_compare_op" getter="get_compare_op" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="enable_compare" type="bool" setter="set_enable_compare" getter="get_enable_compare" default="false"> + </member> + <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="0.0"> + </member> + <member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="max_lod" type="float" setter="set_max_lod" getter="get_max_lod" default="1e+20"> + </member> + <member name="min_filter" type="int" setter="set_min_filter" getter="get_min_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="min_lod" type="float" setter="set_min_lod" getter="get_min_lod" default="0.0"> + </member> + <member name="mip_filter" type="int" setter="set_mip_filter" getter="get_mip_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="repeat_u" type="int" setter="set_repeat_u" getter="get_repeat_u" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="repeat_v" type="int" setter="set_repeat_v" getter="get_repeat_v" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="repeat_w" type="int" setter="set_repeat_w" getter="get_repeat_w" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="unnormalized_uvw" type="bool" setter="set_unnormalized_uvw" getter="get_unnormalized_uvw" default="false"> + </member> + <member name="use_anisotropy" type="bool" setter="set_use_anisotropy" getter="get_use_anisotropy" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderBytecode.xml b/doc/classes/RDShaderBytecode.xml new file mode 100644 index 0000000000..7a3501004e --- /dev/null +++ b/doc/classes/RDShaderBytecode.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderBytecode" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_stage_bytecode" qualifiers="const"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="get_stage_compile_error" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="set_stage_bytecode"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="bytecode" type="PackedByteArray"> + </argument> + <description> + </description> + </method> + <method name="set_stage_compile_error"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="compile_error" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="bytecode_compute" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_fragment" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_tesselation_control" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_tesselation_evaluation" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_vertex" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="compile_error_compute" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_fragment" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_tesselation_control" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_tesselation_evaluation" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_vertex" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderFile.xml b/doc/classes/RDShaderFile.xml new file mode 100644 index 0000000000..14e70d53ea --- /dev/null +++ b/doc/classes/RDShaderFile.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderFile" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_bytecode" qualifiers="const"> + <return type="RDShaderBytecode"> + </return> + <argument index="0" name="version" type="StringName" default="@"""> + </argument> + <description> + </description> + </method> + <method name="get_version_list" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + </description> + </method> + <method name="set_bytecode"> + <return type="void"> + </return> + <argument index="0" name="bytecode" type="RDShaderBytecode"> + </argument> + <argument index="1" name="version" type="StringName" default="@"""> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_error" type="String" setter="set_base_error" getter="get_base_error" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderSource.xml b/doc/classes/RDShaderSource.xml new file mode 100644 index 0000000000..c1cfd34bb7 --- /dev/null +++ b/doc/classes/RDShaderSource.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderSource" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_stage_source" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="set_stage_source"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="source" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="language" type="int" setter="set_language" getter="get_language" enum="RenderingDevice.ShaderLanguage" default="0"> + </member> + <member name="source_compute" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_fragment" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_tesselation_control" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_tesselation_evaluation" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_vertex" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml new file mode 100644 index 0000000000..664d4cadff --- /dev/null +++ b/doc/classes/RDTextureFormat.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDTextureFormat" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_shareable_format"> + <return type="void"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <description> + </description> + </method> + <method name="remove_shareable_format"> + <return type="void"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="array_layers" type="int" setter="set_array_layers" getter="get_array_layers" default="1"> + </member> + <member name="depth" type="int" setter="set_depth" getter="get_depth" default="1"> + </member> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="8"> + </member> + <member name="height" type="int" setter="set_height" getter="get_height" default="1"> + </member> + <member name="mipmaps" type="int" setter="set_mipmaps" getter="get_mipmaps" default="1"> + </member> + <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0"> + </member> + <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.TextureType" default="1"> + </member> + <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" default="0"> + </member> + <member name="width" type="int" setter="set_width" getter="get_width" default="1"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDTextureView.xml b/doc/classes/RDTextureView.xml new file mode 100644 index 0000000000..73b2a7ae4a --- /dev/null +++ b/doc/classes/RDTextureView.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDTextureView" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format_override" type="int" setter="set_format_override" getter="get_format_override" enum="RenderingDevice.DataFormat" default="226"> + </member> + <member name="swizzle_a" type="int" setter="set_swizzle_a" getter="get_swizzle_a" enum="RenderingDevice.TextureSwizzle" default="6"> + </member> + <member name="swizzle_b" type="int" setter="set_swizzle_b" getter="get_swizzle_b" enum="RenderingDevice.TextureSwizzle" default="5"> + </member> + <member name="swizzle_g" type="int" setter="set_swizzle_g" getter="get_swizzle_g" enum="RenderingDevice.TextureSwizzle" default="4"> + </member> + <member name="swizzle_r" type="int" setter="set_swizzle_r" getter="get_swizzle_r" enum="RenderingDevice.TextureSwizzle" default="3"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDUniform.xml b/doc/classes/RDUniform.xml new file mode 100644 index 0000000000..e5bace32af --- /dev/null +++ b/doc/classes/RDUniform.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDUniform" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="RID"> + </argument> + <description> + </description> + </method> + <method name="clear_ids"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_ids" qualifiers="const"> + <return type="Array"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="binding" type="int" setter="set_binding" getter="get_binding" default="0"> + </member> + <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.UniformType" default="3"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDVertexAttribute.xml b/doc/classes/RDVertexAttribute.xml new file mode 100644 index 0000000000..56fe40b51d --- /dev/null +++ b/doc/classes/RDVertexAttribute.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDVertexAttribute" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="226"> + </member> + <member name="frequency" type="int" setter="set_frequency" getter="get_frequency" enum="RenderingDevice.VertexFrequency" default="0"> + </member> + <member name="location" type="int" setter="set_location" getter="get_location" default="0"> + </member> + <member name="offset" type="int" setter="set_offset" getter="get_offset" default="0"> + </member> + <member name="stride" type="int" setter="set_stride" getter="get_stride" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 2615f0a2e9..8a44d213e8 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -7,7 +7,1593 @@ <tutorials> </tutorials> <methods> + <method name="buffer_get_data"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="buffer" type="RID"> + </argument> + <description> + </description> + </method> + <method name="buffer_update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="buffer" type="RID"> + </argument> + <argument index="1" name="offset" type="int"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <argument index="3" name="data" type="PackedByteArray"> + </argument> + <argument index="4" name="sync_with_draw" type="bool" default="true"> + </argument> + <description> + </description> + </method> + <method name="capture_timestamp"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="sync_to_draw" type="bool"> + </argument> + <description> + </description> + </method> + <method name="compute_list_add_barrier"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_begin"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="compute_list_bind_compute_pipeline"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="compute_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="compute_list_bind_uniform_set"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="uniform_set" type="RID"> + </argument> + <argument index="2" name="set_index" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_dispatch"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="x_groups" type="int"> + </argument> + <argument index="2" name="y_groups" type="int"> + </argument> + <argument index="3" name="z_groups" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_end"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="compute_list_set_push_constant"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="buffer" type="PackedByteArray"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_pipeline_create"> + <return type="RID"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <description> + </description> + </method> + <method name="compute_pipeline_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="compute_pieline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="create_local_device"> + <return type="RenderingDevice"> + </return> + <description> + </description> + </method> + <method name="draw_list_begin"> + <return type="int"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <argument index="1" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="2" name="final_color_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="3" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="4" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="5" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )"> + </argument> + <argument index="6" name="clear_depth" type="float" default="1.0"> + </argument> + <argument index="7" name="clear_stencil" type="int" default="0"> + </argument> + <argument index="8" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_begin_for_screen"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <argument index="1" name="clear_color" type="Color" default="Color( 0, 0, 0, 1 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_begin_split"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <argument index="1" name="splits" type="int"> + </argument> + <argument index="2" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="3" name="final_color_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="4" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="5" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="6" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )"> + </argument> + <argument index="7" name="clear_depth" type="float" default="1.0"> + </argument> + <argument index="8" name="clear_stencil" type="int" default="0"> + </argument> + <argument index="9" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_index_array"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="index_array" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_render_pipeline"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="render_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_uniform_set"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="uniform_set" type="RID"> + </argument> + <argument index="2" name="set_index" type="int"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_vertex_array"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="vertex_array" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_disable_scissor"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <description> + </description> + </method> + <method name="draw_list_draw"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="use_indices" type="bool"> + </argument> + <argument index="2" name="instances" type="int"> + </argument> + <argument index="3" name="procedural_vertex_count" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="draw_list_enable_scissor"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="rect" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_end"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="draw_list_set_push_constant"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="buffer" type="PackedByteArray"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_create"> + <return type="RID"> + </return> + <argument index="0" name="textures" type="Array"> + </argument> + <argument index="1" name="validate_with_format" type="int" default="-1"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_format_create"> + <return type="int"> + </return> + <argument index="0" name="attachments" type="RDAttachmentFormat[]"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_format_get_texture_samples"> + <return type="int" enum="RenderingDevice.TextureSamples"> + </return> + <argument index="0" name="format" type="int"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_get_format"> + <return type="int"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <description> + </description> + </method> + <method name="free"> + <return type="void"> + </return> + <argument index="0" name="rid" type="RID"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_cpu_time" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_gpu_time" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamps_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_captured_timestamps_frame" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_frame_delay" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="index_array_create"> + <return type="RID"> + </return> + <argument index="0" name="index_buffer" type="RID"> + </argument> + <argument index="1" name="index_offset" type="int"> + </argument> + <argument index="2" name="index_count" type="int"> + </argument> + <description> + </description> + </method> + <method name="index_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_indices" type="int"> + </argument> + <argument index="1" name="format" type="int" enum="RenderingDevice.IndexBufferFormat"> + </argument> + <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <argument index="3" name="arg3" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="limit_get"> + <return type="int"> + </return> + <argument index="0" name="limit" type="int" enum="RenderingDevice.Limit"> + </argument> + <description> + </description> + </method> + <method name="render_pipeline_create"> + <return type="RID"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <argument index="1" name="framebuffer_format" type="int"> + </argument> + <argument index="2" name="vertex_format" type="int"> + </argument> + <argument index="3" name="primitive" type="int" enum="RenderingDevice.RenderPrimitive"> + </argument> + <argument index="4" name="rasterization_state" type="RDPipelineRasterizationState"> + </argument> + <argument index="5" name="multisample_state" type="RDPipelineMultisampleState"> + </argument> + <argument index="6" name="stencil_state" type="RDPipelineDepthStencilState"> + </argument> + <argument index="7" name="color_blend_state" type="RDPipelineColorBlendState"> + </argument> + <argument index="8" name="dynamic_state_flags" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="render_pipeline_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="render_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="sampler_create"> + <return type="RID"> + </return> + <argument index="0" name="state" type="RDSamplerState"> + </argument> + <description> + </description> + </method> + <method name="screen_get_framebuffer_format" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="screen_get_height" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="screen_get_width" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="shader_compile_from_source"> + <return type="RDShaderBytecode"> + </return> + <argument index="0" name="shader_source" type="RDShaderSource"> + </argument> + <argument index="1" name="allow_cache" type="bool" default="true"> + </argument> + <description> + </description> + </method> + <method name="shader_create"> + <return type="RID"> + </return> + <argument index="0" name="shader_data" type="RDShaderBytecode"> + </argument> + <description> + </description> + </method> + <method name="shader_get_vertex_input_attribute_mask"> + <return type="int"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <description> + </description> + </method> + <method name="storage_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="submit"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="sync"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="texture_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="texture_clear"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="color" type="Color"> + </argument> + <argument index="2" name="base_mipmap" type="int"> + </argument> + <argument index="3" name="mipmap_count" type="int"> + </argument> + <argument index="4" name="base_layer" type="int"> + </argument> + <argument index="5" name="layer_count" type="int"> + </argument> + <argument index="6" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_copy"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="from_texture" type="RID"> + </argument> + <argument index="1" name="to_texture" type="RID"> + </argument> + <argument index="2" name="from_pos" type="Vector3"> + </argument> + <argument index="3" name="to_pos" type="Vector3"> + </argument> + <argument index="4" name="size" type="Vector3"> + </argument> + <argument index="5" name="src_mipmap" type="int"> + </argument> + <argument index="6" name="dst_mipmap" type="int"> + </argument> + <argument index="7" name="src_layer" type="int"> + </argument> + <argument index="8" name="dst_layer" type="int"> + </argument> + <argument index="9" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_create"> + <return type="RID"> + </return> + <argument index="0" name="format" type="RDTextureFormat"> + </argument> + <argument index="1" name="view" type="RDTextureView"> + </argument> + <argument index="2" name="data" type="PackedByteArray[]" default="[ ]"> + </argument> + <description> + </description> + </method> + <method name="texture_create_shared"> + <return type="RID"> + </return> + <argument index="0" name="view" type="RDTextureView"> + </argument> + <argument index="1" name="with_texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_create_shared_from_slice"> + <return type="RID"> + </return> + <argument index="0" name="view" type="RDTextureView"> + </argument> + <argument index="1" name="with_texture" type="RID"> + </argument> + <argument index="2" name="layer" type="int"> + </argument> + <argument index="3" name="mipmap" type="int"> + </argument> + <argument index="4" name="slice_type" type="int" enum="RenderingDevice.TextureSliceType" default="0"> + </argument> + <description> + </description> + </method> + <method name="texture_get_data"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="layer" type="int"> + </argument> + <description> + </description> + </method> + <method name="texture_is_format_supported_for_usage" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <argument index="1" name="usage_flags" type="int"> + </argument> + <description> + </description> + </method> + <method name="texture_is_shared"> + <return type="bool"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_resolve_multisample"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="from_texture" type="RID"> + </argument> + <argument index="1" name="to_texture" type="RID"> + </argument> + <argument index="2" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="layer" type="int"> + </argument> + <argument index="2" name="data" type="PackedByteArray"> + </argument> + <argument index="3" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="uniform_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="uniform_set_create"> + <return type="RID"> + </return> + <argument index="0" name="uniforms" type="Array"> + </argument> + <argument index="1" name="shader" type="RID"> + </argument> + <argument index="2" name="shader_set" type="int"> + </argument> + <description> + </description> + </method> + <method name="uniform_set_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="uniform_set" type="RID"> + </argument> + <description> + </description> + </method> + <method name="vertex_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="vertex_format_create"> + <return type="int"> + </return> + <argument index="0" name="vertex_descriptions" type="RDVertexAttribute[]"> + </argument> + <description> + </description> + </method> </methods> <constants> + <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B4G4R4A4_UNORM_PACK16" value="2" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R5G6B5_UNORM_PACK16" value="3" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B5G6R5_UNORM_PACK16" value="4" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R5G5B5A1_UNORM_PACK16" value="5" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B5G5R5A1_UNORM_PACK16" value="6" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A1R5G5B5_UNORM_PACK16" value="7" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_UNORM" value="8" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SNORM" value="9" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_USCALED" value="10" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SSCALED" value="11" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_UINT" value="12" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SINT" value="13" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SRGB" value="14" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_UNORM" value="15" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SNORM" value="16" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_USCALED" value="17" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SSCALED" value="18" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_UINT" value="19" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SINT" value="20" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SRGB" value="21" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_UNORM" value="22" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SNORM" value="23" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_USCALED" value="24" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SSCALED" value="25" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_UINT" value="26" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SINT" value="27" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SRGB" value="28" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_UNORM" value="29" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SNORM" value="30" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_USCALED" value="31" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SSCALED" value="32" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_UINT" value="33" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SINT" value="34" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SRGB" value="35" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_UNORM" value="36" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SNORM" value="37" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_USCALED" value="38" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SSCALED" value="39" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_UINT" value="40" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SINT" value="41" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SRGB" value="42" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_UNORM" value="43" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SNORM" value="44" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_USCALED" value="45" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SSCALED" value="46" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_UINT" value="47" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SINT" value="48" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SRGB" value="49" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_UNORM_PACK32" value="50" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SNORM_PACK32" value="51" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_USCALED_PACK32" value="52" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SSCALED_PACK32" value="53" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_UINT_PACK32" value="54" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SINT_PACK32" value="55" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SRGB_PACK32" value="56" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_UNORM_PACK32" value="57" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SNORM_PACK32" value="58" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_USCALED_PACK32" value="59" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SSCALED_PACK32" value="60" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_UINT_PACK32" value="61" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SINT_PACK32" value="62" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_UNORM_PACK32" value="63" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SNORM_PACK32" value="64" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_USCALED_PACK32" value="65" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SSCALED_PACK32" value="66" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_UINT_PACK32" value="67" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SINT_PACK32" value="68" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_UNORM" value="69" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SNORM" value="70" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_USCALED" value="71" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SSCALED" value="72" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_UINT" value="73" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SINT" value="74" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SFLOAT" value="75" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_UNORM" value="76" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SNORM" value="77" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_USCALED" value="78" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SSCALED" value="79" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_UINT" value="80" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SINT" value="81" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SFLOAT" value="82" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_UNORM" value="83" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SNORM" value="84" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_USCALED" value="85" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SSCALED" value="86" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_UINT" value="87" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SINT" value="88" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SFLOAT" value="89" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_UNORM" value="90" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SNORM" value="91" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_USCALED" value="92" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SSCALED" value="93" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_UINT" value="94" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SINT" value="95" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SFLOAT" value="96" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_UINT" value="97" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_SINT" value="98" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_SFLOAT" value="99" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_UINT" value="100" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_SINT" value="101" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_SFLOAT" value="102" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_UINT" value="103" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_SINT" value="104" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_SFLOAT" value="105" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_UINT" value="106" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_SINT" value="107" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_SFLOAT" value="108" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_UINT" value="109" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_SINT" value="110" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_SFLOAT" value="111" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_UINT" value="112" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_SINT" value="113" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_SFLOAT" value="114" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_UINT" value="115" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_SINT" value="116" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_SFLOAT" value="117" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_UINT" value="118" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_SINT" value="119" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_SFLOAT" value="120" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B10G11R11_UFLOAT_PACK32" value="121" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32" value="122" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D16_UNORM" value="123" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_X8_D24_UNORM_PACK32" value="124" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D32_SFLOAT" value="125" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_S8_UINT" value="126" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D16_UNORM_S8_UINT" value="127" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D24_UNORM_S8_UINT" value="128" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D32_SFLOAT_S8_UINT" value="129" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGB_UNORM_BLOCK" value="130" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGB_SRGB_BLOCK" value="131" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGBA_UNORM_BLOCK" value="132" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGBA_SRGB_BLOCK" value="133" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC2_UNORM_BLOCK" value="134" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC2_SRGB_BLOCK" value="135" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC3_UNORM_BLOCK" value="136" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC3_SRGB_BLOCK" value="137" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC4_UNORM_BLOCK" value="138" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC4_SNORM_BLOCK" value="139" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC5_UNORM_BLOCK" value="140" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC5_SNORM_BLOCK" value="141" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC6H_UFLOAT_BLOCK" value="142" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC6H_SFLOAT_BLOCK" value="143" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC7_UNORM_BLOCK" value="144" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC7_SRGB_BLOCK" value="145" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK" value="146" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK" value="147" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK" value="148" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK" value="149" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK" value="150" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK" value="151" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11_UNORM_BLOCK" value="152" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11_SNORM_BLOCK" value="153" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11G11_UNORM_BLOCK" value="154" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11G11_SNORM_BLOCK" value="155" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_4x4_UNORM_BLOCK" value="156" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_4x4_SRGB_BLOCK" value="157" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x4_UNORM_BLOCK" value="158" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x4_SRGB_BLOCK" value="159" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x5_UNORM_BLOCK" value="160" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x5_SRGB_BLOCK" value="161" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x5_UNORM_BLOCK" value="162" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x5_SRGB_BLOCK" value="163" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x6_UNORM_BLOCK" value="164" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x6_SRGB_BLOCK" value="165" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x5_UNORM_BLOCK" value="166" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x5_SRGB_BLOCK" value="167" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x6_UNORM_BLOCK" value="168" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x6_SRGB_BLOCK" value="169" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x8_UNORM_BLOCK" value="170" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x8_SRGB_BLOCK" value="171" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x5_UNORM_BLOCK" value="172" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x5_SRGB_BLOCK" value="173" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x6_UNORM_BLOCK" value="174" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x6_SRGB_BLOCK" value="175" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x8_UNORM_BLOCK" value="176" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x8_SRGB_BLOCK" value="177" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x10_UNORM_BLOCK" value="178" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x10_SRGB_BLOCK" value="179" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x10_UNORM_BLOCK" value="180" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x10_SRGB_BLOCK" value="181" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x12_UNORM_BLOCK" value="182" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x12_SRGB_BLOCK" value="183" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8B8G8R8_422_UNORM" value="184" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8G8_422_UNORM" value="185" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM" value="186" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM" value="187" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM" value="188" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM" value="189" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM" value="190" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6_UNORM_PACK16" value="191" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6G10X6_UNORM_2PACK16" value="192" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16" value="193" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16" value="194" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16" value="195" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16" value="196" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16" value="197" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16" value="198" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16" value="199" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16" value="200" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4_UNORM_PACK16" value="201" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4G12X4_UNORM_2PACK16" value="202" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16" value="203" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16" value="204" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16" value="205" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16" value="206" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16" value="207" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16" value="208" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16" value="209" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16" value="210" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16B16G16R16_422_UNORM" value="211" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B16G16R16G16_422_UNORM" value="212" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM" value="213" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM" value="214" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM" value="215" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM" value="216" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM" value="217" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG" value="218" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG" value="219" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG" value="220" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG" value="221" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG" value="222" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG" value="223" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG" value="224" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG" value="225" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_MAX" value="226" enum="DataFormat"> + </constant> + <constant name="TEXTURE_TYPE_1D" value="0" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_2D" value="1" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_3D" value="2" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_CUBE" value="3" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_1D_ARRAY" value="4" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_2D_ARRAY" value="5" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_CUBE_ARRAY" value="6" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_MAX" value="7" enum="TextureType"> + </constant> + <constant name="TEXTURE_SAMPLES_1" value="0" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_2" value="1" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_4" value="2" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_8" value="3" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_16" value="4" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_32" value="5" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_64" value="6" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_MAX" value="7" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_USAGE_SAMPLING_BIT" value="1" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_COLOR_ATTACHMENT_BIT" value="2" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_STORAGE_ATOMIC_BIT" value="16" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CPU_READ_BIT" value="32" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_UPDATE_BIT" value="64" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_COPY_FROM_BIT" value="128" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_COPY_TO_BIT" value="256" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT" value="512" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_SWIZZLE_IDENTITY" value="0" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_ZERO" value="1" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_ONE" value="2" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_R" value="3" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_G" value="4" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_B" value="5" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_A" value="6" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_MAX" value="7" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SLICE_2D" value="0" enum="TextureSliceType"> + </constant> + <constant name="TEXTURE_SLICE_CUBEMAP" value="1" enum="TextureSliceType"> + </constant> + <constant name="TEXTURE_SLICE_3D" value="2" enum="TextureSliceType"> + </constant> + <constant name="SAMPLER_FILTER_NEAREST" value="0" enum="SamplerFilter"> + </constant> + <constant name="SAMPLER_FILTER_LINEAR" value="1" enum="SamplerFilter"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_REPEAT" value="0" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MIRRORED_REPEAT" value="1" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE" value="2" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER" value="3" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE" value="4" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MAX" value="5" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK" value="0" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK" value="1" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK" value="2" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK" value="3" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE" value="4" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE" value="5" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_MAX" value="6" enum="SamplerBorderColor"> + </constant> + <constant name="VERTEX_FREQUENCY_VERTEX" value="0" enum="VertexFrequency"> + </constant> + <constant name="VERTEX_FREQUENCY_INSTANCE" value="1" enum="VertexFrequency"> + </constant> + <constant name="INDEX_BUFFER_FORMAT_UINT16" value="0" enum="IndexBufferFormat"> + </constant> + <constant name="INDEX_BUFFER_FORMAT_UINT32" value="1" enum="IndexBufferFormat"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE" value="1" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_TEXTURE" value="2" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_IMAGE" value="3" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_TEXTURE_BUFFER" value="4" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER" value="5" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_IMAGE_BUFFER" value="6" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_UNIFORM_BUFFER" value="7" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_STORAGE_BUFFER" value="8" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_INPUT_ATTACHMENT" value="9" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_MAX" value="10" enum="UniformType"> + </constant> + <constant name="RENDER_PRIMITIVE_POINTS" value="0" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINES" value="1" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINES_WITH_ADJACENCY" value="2" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINESTRIPS" value="3" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY" value="4" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLES" value="5" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY" value="6" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS" value="7" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY" value="8" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX" value="9" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TESSELATION_PATCH" value="10" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_MAX" value="11" enum="RenderPrimitive"> + </constant> + <constant name="POLYGON_CULL_DISABLED" value="0" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_CULL_FRONT" value="1" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_CULL_BACK" value="2" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_FRONT_FACE_CLOCKWISE" value="0" enum="PolygonFrontFace"> + </constant> + <constant name="POLYGON_FRONT_FACE_COUNTER_CLOCKWISE" value="1" enum="PolygonFrontFace"> + </constant> + <constant name="STENCIL_OP_KEEP" value="0" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_ZERO" value="1" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_REPLACE" value="2" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INCREMENT_AND_CLAMP" value="3" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_DECREMENT_AND_CLAMP" value="4" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INVERT" value="5" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INCREMENT_AND_WRAP" value="6" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_DECREMENT_AND_WRAP" value="7" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_MAX" value="8" enum="StencilOperation"> + </constant> + <constant name="COMPARE_OP_NEVER" value="0" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_LESS" value="1" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_EQUAL" value="2" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_LESS_OR_EQUAL" value="3" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_GREATER" value="4" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_NOT_EQUAL" value="5" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_GREATER_OR_EQUAL" value="6" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_ALWAYS" value="7" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_MAX" value="8" enum="CompareOperator"> + </constant> + <constant name="LOGIC_OP_CLEAR" value="0" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND" value="1" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND_REVERSE" value="2" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_COPY" value="3" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND_INVERTED" value="4" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NO_OP" value="5" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_XOR" value="6" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR" value="7" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NOR" value="8" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_EQUIVALENT" value="9" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_INVERT" value="10" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR_REVERSE" value="11" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_COPY_INVERTED" value="12" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR_INVERTED" value="13" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NAND" value="14" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_SET" value="15" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_MAX" value="16" enum="LogicOperation"> + </constant> + <constant name="BLEND_FACTOR_ZERO" value="0" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE" value="1" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_COLOR" value="2" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC_COLOR" value="3" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_DST_COLOR" value="4" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_DST_COLOR" value="5" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_ALPHA" value="6" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC_ALPHA" value="7" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_DST_ALPHA" value="8" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_DST_ALPHA" value="9" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_CONSTANT_COLOR" value="10" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR" value="11" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_CONSTANT_ALPHA" value="12" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="13" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_ALPHA_SATURATE" value="14" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC1_COLOR" value="15" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_COLOR" value="16" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC1_ALPHA" value="17" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA" value="18" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_MAX" value="19" enum="BlendFactor"> + </constant> + <constant name="BLEND_OP_ADD" value="0" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_SUBTRACT" value="1" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_REVERSE_SUBTRACT" value="2" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MINIMUM" value="3" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MAXIMUM" value="4" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MAX" value="5" enum="BlendOperation"> + </constant> + <constant name="DYNAMIC_STATE_LINE_WIDTH" value="1" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_DEPTH_BIAS" value="2" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_BLEND_CONSTANTS" value="4" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_DEPTH_BOUNDS" value="8" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_COMPARE_MASK" value="16" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_WRITE_MASK" value="32" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_REFERENCE" value="64" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction"> + </constant> + <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_CONTINUE" value="2" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_MAX" value="3" enum="FinalAction"> + </constant> + <constant name="SHADER_STAGE_VERTEX" value="0" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_FRAGMENT" value="1" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_CONTROL" value="2" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_EVALUATION" value="3" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_COMPUTE" value="4" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_MAX" value="5" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_VERTEX_BIT" value="1" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_FRAGMENT_BIT" value="2" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_CONTROL_BIT" value="4" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_EVALUATION_BIT" value="8" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_COMPUTE_BIT" value="16" enum="ShaderStage"> + </constant> + <constant name="SHADER_LANGUAGE_GLSL" value="0" enum="ShaderLanguage"> + </constant> + <constant name="SHADER_LANGUAGE_HLSL" value="1" enum="ShaderLanguage"> + </constant> + <constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS" value="1" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURES_PER_UNIFORM_SET" value="2" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET" value="3" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET" value="4" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET" value="5" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET" value="6" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_DRAW_INDEXED_INDEX" value="7" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_HEIGHT" value="8" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_WIDTH" value="9" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_ARRAY_LAYERS" value="10" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_1D" value="11" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_2D" value="12" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_3D" value="13" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_CUBE" value="14" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURES_PER_SHADER_STAGE" value="15" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE" value="16" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE" value="17" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE" value="18" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE" value="19" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_PUSH_CONSTANT_SIZE" value="20" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFER_SIZE" value="21" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET" value="22" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES" value="23" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_BINDINGS" value="24" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE" value="25" enum="Limit"> + </constant> + <constant name="LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT" value="26" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE" value="27" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X" value="28" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y" value="29" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z" value="30" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS" value="31" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X" value="32" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y" value="33" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit"> + </constant> + <constant name="INVALID_ID" value="-1"> + </constant> + <constant name="INVALID_FORMAT_ID" value="-1"> + </constant> </constants> </class> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index bfdcf1bb79..4e0762a68b 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -4,12 +4,12 @@ Server for anything visible. </brief_description> <description> - Server for anything visible. The visual server is the API backend for everything visible. The whole scene system mounts on it to display. - The visual server is completely opaque, the internals are entirely implementation specific and cannot be accessed. - The visual server can be used to bypass the scene system entirely. + Server for anything visible. The rendering server is the API backend for everything visible. The whole scene system mounts on it to display. + The rendering server is completely opaque, the internals are entirely implementation specific and cannot be accessed. + The rendering server can be used to bypass the scene system entirely. Resources are created using the [code]*_create[/code] functions. All objects are drawn to a viewport. You can use the [Viewport] attached to the [SceneTree] or you can create one yourself with [method viewport_create]. When using a custom scenario or canvas, the scenario or canvas needs to be attached to the viewport using [method viewport_set_scenario] or [method viewport_attach_canvas]. - In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the visual server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create]. + In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the rendering server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create]. Similarly in 2D, a canvas is needed to draw all canvas items. In 3D, all visible objects are comprised of a resource and an instance. A resource can be a mesh, a particle system, a light, or any other 3D object. In order to be visible resources must be attached to an instance using [method instance_set_base]. The instance must also be attached to the scenario using [method instance_set_scenario] in order to be visible. In 2D, all visible objects are some form of canvas item. In order to be visible, a canvas item needs to be the child of a canvas attached to a viewport, or it needs to be the child of another canvas item that is eventually attached to the canvas. @@ -947,6 +947,58 @@ Returns the id of a white texture. Creates one if none exists. </description> </method> + <method name="global_variable_add"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType"> + </argument> + <argument index="2" name="default_value" type="Variant"> + </argument> + <description> + </description> + </method> + <method name="global_variable_get" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_get_list" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + </description> + </method> + <method name="global_variable_get_type" qualifiers="const"> + <return type="int" enum="RenderingServer.GlobalVariableType"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_remove"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_set"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + </description> + </method> <method name="has_changed" qualifiers="const"> <return type="bool"> </return> @@ -1113,7 +1165,7 @@ <return type="void"> </return> <description> - Initializes the visual server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything. + Initializes the rendering server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything. </description> </method> <method name="instance_attach_object_instance_id"> @@ -3110,12 +3162,6 @@ <constant name="MAX_CURSORS" value="8"> Unused enum in Godot 3.x. </constant> - <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128"> - The minimum renderpriority of all materials. - </constant> - <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127"> - The maximum renderpriority of all materials. - </constant> <constant name="TEXTURE_LAYERED_2D_ARRAY" value="0" enum="TextureLayeredType"> </constant> <constant name="TEXTURE_LAYERED_CUBEMAP" value="1" enum="TextureLayeredType"> @@ -3149,6 +3195,12 @@ <constant name="SHADER_MAX" value="4" enum="ShaderMode"> Represents the size of the [enum ShaderMode] enum. </constant> + <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128"> + The minimum renderpriority of all materials. + </constant> + <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127"> + The maximum renderpriority of all materials. + </constant> <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> Array is a vertex array. </constant> @@ -3224,14 +3276,14 @@ <constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat"> Flag used to mark a compressed index array. </constant> + <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> + Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. + </constant> <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat"> Flag used to mark that the array contains 2D vertices. </constant> <constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="1048576" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> - Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. - </constant> <constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType"> Primitive to draw consists of points. </constant> @@ -3307,6 +3359,7 @@ Proportion of shadow atlas occupied by the third split. The fourth split occupies the rest. </constant> <constant name="LIGHT_PARAM_SHADOW_FADE_START" value="12" enum="LightParam"> + Proportion of shadow max distance where the shadow will start to fade out. </constant> <constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="13" enum="LightParam"> Normal bias used to offset shadow lookup by object normal. Can be used to fix self-shadowing artifacts. @@ -3314,10 +3367,15 @@ <constant name="LIGHT_PARAM_SHADOW_BIAS" value="14" enum="LightParam"> Bias the shadow lookup to fix self-shadowing artifacts. </constant> - <constant name="LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="LightParam"> - Increases bias on further splits to fix self-shadowing that only occurs far away from the camera. + <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"> + 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_TRANSMITTANCE_BIAS" value="17" enum="LightParam"> </constant> - <constant name="LIGHT_PARAM_MAX" value="16" enum="LightParam"> + <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam"> Represents the size of the [enum LightParam] enum. </constant> <constant name="LIGHT_OMNI_SHADOW_DUAL_PARABOLOID" value="0" enum="LightOmniShadowMode"> @@ -3347,6 +3405,16 @@ <constant name="REFLECTION_PROBE_UPDATE_ALWAYS" value="1" enum="ReflectionProbeUpdateMode"> Reflection probe will update each frame. This mode is necessary to capture moving objects. </constant> + <constant name="DECAL_TEXTURE_ALBEDO" value="0" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_NORMAL" value="1" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_ORM" value="2" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_EMISSION" value="3" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_MAX" value="4" enum="DecalTexture"> + </constant> <constant name="PARTICLES_DRAW_ORDER_INDEX" value="0" enum="ParticlesDrawOrder"> Draw particles in the order that they appear in the particles array. </constant> @@ -3383,22 +3451,24 @@ Multisample antialiasing is disabled. </constant> <constant name="VIEWPORT_MSAA_2X" value="1" enum="ViewportMSAA"> - Multisample antialiasing is set to 2×. + Multisample antialiasing uses 2 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_4X" value="2" enum="ViewportMSAA"> - Multisample antialiasing is set to 4×. + Multisample antialiasing uses 4 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_8X" value="3" enum="ViewportMSAA"> - Multisample antialiasing is set to 8×. + Multisample antialiasing uses 8 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA"> - Multisample antialiasing is set to 16×. + Multisample antialiasing uses 16 samples per pixel. + </constant> + <constant name="VIEWPORT_MSAA_MAX" value="5" enum="ViewportMSAA"> + </constant> + <constant name="VIEWPORT_SCREEN_SPACE_AA_DISABLED" value="0" enum="ViewportScreenSpaceAA"> </constant> - <constant name="VIEWPORT_MSAA_EXT_2X" value="5" enum="ViewportMSAA"> - Multisample antialiasing is set to 2× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go). + <constant name="VIEWPORT_SCREEN_SPACE_AA_FXAA" value="1" enum="ViewportScreenSpaceAA"> </constant> - <constant name="VIEWPORT_MSAA_EXT_4X" value="6" enum="ViewportMSAA"> - Multisample antialiasing is set to 4× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go). + <constant name="VIEWPORT_SCREEN_SPACE_AA_MAX" value="2" enum="ViewportScreenSpaceAA"> </constant> <constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo"> Number of objects drawn in a single frame. @@ -3425,37 +3495,54 @@ Debug draw is disabled. Default setting. </constant> <constant name="VIEWPORT_DEBUG_DRAW_UNSHADED" value="1" enum="ViewportDebugDraw"> - Debug draw sets objects to unshaded. + Objects are displayed without light information. </constant> <constant name="VIEWPORT_DEBUG_DRAW_LIGHTING" value="2" enum="ViewportDebugDraw"> + Objects are displayed with only light information. </constant> <constant name="VIEWPORT_DEBUG_DRAW_OVERDRAW" value="3" enum="ViewportDebugDraw"> - Overwrites clear color to [code](0,0,0,0)[/code]. + Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others. </constant> <constant name="VIEWPORT_DEBUG_DRAW_WIREFRAME" value="4" enum="ViewportDebugDraw"> Debug draw draws objects in wireframe. </constant> <constant name="VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="ViewportDebugDraw"> + Normal buffer is drawn instead of regular scene so you can see the per-pixel normals that will be used by post-processing effects. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="ViewportDebugDraw"> + Objects are displayed with only the albedo value from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="ViewportDebugDraw"> + Objects are displayed with only the lighting value from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="ViewportDebugDraw"> + Objects are displayed with only the emission color from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="ViewportDebugDraw"> + Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="ViewportDebugDraw"> + Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="ViewportDebugDraw"> </constant> <constant name="VIEWPORT_DEBUG_DRAW_SSAO" value="12" enum="ViewportDebugDraw"> + Draws the screen space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="ViewportDebugDraw"> + Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="14" enum="ViewportDebugDraw"> + Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order they will be colored red, green, blue, yellow. + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="15" enum="ViewportDebugDraw"> </constant> <constant name="SKY_MODE_QUALITY" value="0" enum="SkyMode"> + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. </constant> <constant name="SKY_MODE_REALTIME" value="1" enum="SkyMode"> + Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. + [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256]. </constant> <constant name="ENV_BG_CLEAR_COLOR" value="0" enum="EnvironmentBG"> Use the clear color as background. @@ -3479,28 +3566,40 @@ Represents the size of the [enum EnvironmentBG] enum. </constant> <constant name="ENV_AMBIENT_SOURCE_BG" value="0" enum="EnvironmentAmbientSource"> + Gather ambient light from whichever source is specified as the background. </constant> <constant name="ENV_AMBIENT_SOURCE_DISABLED" value="1" enum="EnvironmentAmbientSource"> + Disable ambient light. </constant> <constant name="ENV_AMBIENT_SOURCE_COLOR" value="2" enum="EnvironmentAmbientSource"> + Specify a specific [Color] for ambient light. </constant> <constant name="ENV_AMBIENT_SOURCE_SKY" value="3" enum="EnvironmentAmbientSource"> + Gather ambient light from the [Sky] regardless of what the background is. </constant> <constant name="ENV_REFLECTION_SOURCE_BG" value="0" enum="EnvironmentReflectionSource"> + Use the background for reflections. </constant> <constant name="ENV_REFLECTION_SOURCE_DISABLED" value="1" enum="EnvironmentReflectionSource"> + Disable reflections. </constant> <constant name="ENV_REFLECTION_SOURCE_SKY" value="2" enum="EnvironmentReflectionSource"> + Use the [Sky] for reflections regardless of what the background is. </constant> <constant name="ENV_GLOW_BLEND_MODE_ADDITIVE" value="0" enum="EnvironmentGlowBlendMode"> + Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. </constant> <constant name="ENV_GLOW_BLEND_MODE_SCREEN" value="1" enum="EnvironmentGlowBlendMode"> + Screen glow blending mode. Increases brightness, used frequently with bloom. </constant> <constant name="ENV_GLOW_BLEND_MODE_SOFTLIGHT" value="2" enum="EnvironmentGlowBlendMode"> + Soft light glow blending mode. Modifies contrast, exposes shadows and highlights (vivid bloom). </constant> <constant name="ENV_GLOW_BLEND_MODE_REPLACE" value="3" enum="EnvironmentGlowBlendMode"> + Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness. </constant> <constant name="ENV_GLOW_BLEND_MODE_MIX" value="4" enum="EnvironmentGlowBlendMode"> + Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="ENV_TONE_MAPPER_LINEAR" value="0" enum="EnvironmentToneMapper"> Output color as they came in. @@ -3514,6 +3613,14 @@ <constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper"> Use the ACES tonemapper. </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_LOW" value="1" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_MEDIUM" value="2" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_HIGH" value="3" enum="EnvironmentSSRRoughnessQuality"> + </constant> <constant name="ENV_SSAO_BLUR_DISABLED" value="0" enum="EnvironmentSSAOBlur"> Disables the blur set for SSAO. Will make SSAO look noisier. </constant> @@ -3533,23 +3640,51 @@ Medium quality screen space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality"> - Highest quality screen space ambient occlusion. + High quality screen space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_ULTRA" value="3" enum="EnvironmentSSAOQuality"> + Highest quality screen space ambient occlusion. + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_DISABLED" value="0" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_LOW" value="1" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_MEDIUM" value="2" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_HIGH" value="3" enum="SubSurfaceScatteringQuality"> </constant> <constant name="DOF_BLUR_QUALITY_VERY_LOW" value="0" enum="DOFBlurQuality"> + Lowest quality DOF blur. This is the fastest setting, but you may be able to see filtering artifacts. </constant> <constant name="DOF_BLUR_QUALITY_LOW" value="1" enum="DOFBlurQuality"> + Low quality DOF blur. </constant> <constant name="DOF_BLUR_QUALITY_MEDIUM" value="2" enum="DOFBlurQuality"> + Medium quality DOF blur. </constant> <constant name="DOF_BLUR_QUALITY_HIGH" value="3" enum="DOFBlurQuality"> + Highest quality DOF blur. Results in the smoothest looking blur by taking the most samples, but is also significantly slower. </constant> <constant name="DOF_BOKEH_BOX" value="0" enum="DOFBokehShape"> + Calculate the DOF blur using a box filter. The fastest option, but results in obvious lines in blur pattern. </constant> <constant name="DOF_BOKEH_HEXAGON" value="1" enum="DOFBokehShape"> + Calculates DOF blur using a hexagon shaped filter. </constant> <constant name="DOF_BOKEH_CIRCLE" value="2" enum="DOFBokehShape"> + Calculates DOF blur using a circle shaped filter. Best quality and most realistic, but slowest. Use only for areas where a lot of performance can be dedicated to post-processing (e.g. cutscenes). + </constant> + <constant name="SHADOW_QUALITY_HARD" value="0" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_LOW" value="1" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="2" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_HIGH" value="3" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_ULTRA" value="4" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_MAX" value="5" enum="ShadowQuality"> </constant> <constant name="SCENARIO_DEBUG_DISABLED" value="0" enum="ScenarioDebugMode"> Do not use a debug mode. @@ -3584,13 +3719,16 @@ <constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType"> The instance is a reflection probe. </constant> - <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType"> + <constant name="INSTANCE_DECAL" value="7" enum="InstanceType"> + The instance is a decal. + </constant> + <constant name="INSTANCE_GI_PROBE" value="8" enum="InstanceType"> The instance is a GI probe. </constant> - <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="8" enum="InstanceType"> + <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="9" enum="InstanceType"> The instance is a lightmap capture. </constant> - <constant name="INSTANCE_MAX" value="9" enum="InstanceType"> + <constant name="INSTANCE_MAX" value="10" enum="InstanceType"> Represents the size of the [enum InstanceType] enum. </constant> <constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType"> @@ -3600,6 +3738,7 @@ Allows the instance to be used in baked lighting. </constant> <constant name="INSTANCE_FLAG_USE_DYNAMIC_GI" value="1" enum="InstanceFlags"> + Allows the instance to be used with dynamic global illumination. </constant> <constant name="INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="2" enum="InstanceFlags"> When set, manually requests to draw geometry on next frame. @@ -3629,30 +3768,43 @@ The nine patch gets filled with tiles where needed and stretches them a bit if needed. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_DEFAULT" value="0" enum="CanvasItemTextureFilter"> + Uses the default filter mode for this [Viewport]. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="1" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="2" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_MAX" value="7" enum="CanvasItemTextureFilter"> + Max value for [enum CanvasItemTextureFilter] enum. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT" value="0" enum="CanvasItemTextureRepeat"> + Uses the default repeat mode for this [Viewport]. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="1" enum="CanvasItemTextureRepeat"> + Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="2" enum="CanvasItemTextureRepeat"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="3" enum="CanvasItemTextureRepeat"> + Flip the texture when repeating so that the edge lines up instead of abruptly changing. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat"> + Max value for [enum CanvasItemTextureRepeat] enum. </constant> <constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode"> Adds light color additive to the canvas. @@ -3676,6 +3828,7 @@ Use PCF13 filtering to filter canvas light shadows. </constant> <constant name="CANVAS_LIGHT_FILTER_MAX" value="3" enum="CanvasLightShadowFilter"> + Max value of the [enum CanvasLightShadowFilter] enum. </constant> <constant name="CANVAS_OCCLUDER_POLYGON_CULL_DISABLED" value="0" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is disabled. @@ -3686,6 +3839,64 @@ <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> + <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType"> + </constant> <constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> The amount of objects in the frame. </constant> diff --git a/doc/classes/ResourceFormatLoaderCrypto.xml b/doc/classes/ResourceFormatLoaderCrypto.xml deleted file mode 100644 index fda529fdbd..0000000000 --- a/doc/classes/ResourceFormatLoaderCrypto.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceFormatLoaderCrypto" inherits="ResourceFormatLoader" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/ResourceFormatSaverCrypto.xml b/doc/classes/ResourceFormatSaverCrypto.xml deleted file mode 100644 index 31db8ff4f5..0000000000 --- a/doc/classes/ResourceFormatSaverCrypto.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceFormatSaverCrypto" inherits="ResourceFormatSaver" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index e746d7fc96..8379fc5b58 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -81,7 +81,7 @@ </description> </method> <method name="get_colliding_bodies" qualifiers="const"> - <return type="Array"> + <return type="Node2D[]"> </return> <description> Returns a list of the bodies colliding with this one. Use [member contacts_reported] to set the maximum number reported. You must also set [member contact_monitor] to [code]true[/code]. diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index 10d6e5f578..f0ad781f77 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -4,6 +4,7 @@ Godot editor's script editor. </brief_description> <description> + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_script_editor]. </description> <tutorials> </tutorials> diff --git a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml b/doc/classes/ShaderGlobalsOverride.xml index b20595b4f6..2aa00aa5a9 100644 --- a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml +++ b/doc/classes/ShaderGlobalsOverride.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsServer3D" inherits="PhysicsServer3D" version="4.0"> +<class name="ShaderGlobalsOverride" inherits="Node" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 08404fb467..4460b519fc 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -157,7 +157,7 @@ <method name="physical_bones_start_simulation"> <return type="void"> </return> - <argument index="0" name="bones" type="Array" default="[ ]"> + <argument index="0" name="bones" type="StringName[]" default="[ ]"> </argument> <description> </description> diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml index f574f42431..78c75d9c2b 100644 --- a/doc/classes/Sky.xml +++ b/doc/classes/Sky.xml @@ -49,7 +49,7 @@ Represents the size of the [enum RadianceSize] enum. </constant> <constant name="PROCESS_MODE_QUALITY" value="0" enum="ProcessMode"> - Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. </constant> <constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode"> Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml index e877050bf8..6014762e3d 100644 --- a/doc/classes/SubViewport.xml +++ b/doc/classes/SubViewport.xml @@ -9,9 +9,6 @@ <methods> </methods> <members> - <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false"> - If [code]true[/code], the sub-viewport will be used in AR/VR process. - </member> <member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="SubViewport.ClearMode" default="0"> The clear mode when the sub-viewport is used as a render target. </member> @@ -27,8 +24,20 @@ <member name="size_2d_override_stretch" type="bool" setter="set_size_2d_override_stretch" getter="is_size_2d_override_stretch_enabled" default="false"> If [code]true[/code], the 2D size override affects stretch as well. </member> + <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false"> + If [code]true[/code], the sub-viewport will be used in AR/VR process. + </member> </members> <constants> + <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode"> + Always clear the render target before drawing. + </constant> + <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode"> + Never clear the render target. + </constant> + <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode"> + Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER]. + </constant> <constant name="UPDATE_DISABLED" value="0" enum="UpdateMode"> Do not update the render target. </constant> @@ -44,14 +53,5 @@ <constant name="UPDATE_ALWAYS" value="4" enum="UpdateMode"> Always update the render target. </constant> - <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode"> - Always clear the render target before drawing. - </constant> - <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode"> - Never clear the render target. - </constant> - <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode"> - Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER]. - </constant> </constants> </class> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 4304a8df5e..eeb6b6cd9d 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -15,6 +15,8 @@ The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method add_uv] or [method add_color], then the last values would be used. Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh. Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices. + See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for procedural geometry generation. + [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes. </description> <tutorials> </tutorials> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index b515b27b31..b7cf93d672 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -433,6 +433,7 @@ </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" /> <member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false"> + If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text. </member> <member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false"> If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added. @@ -611,6 +612,7 @@ <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled. </theme_item> <theme_item name="function_color" type="Color" default="Color( 0.4, 0.64, 0.81, 1 )"> </theme_item> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 5b7694b775..bfe6983f06 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -74,14 +74,14 @@ </description> </method> <method name="get_used_cells" qualifiers="const"> - <return type="Array"> + <return type="Vector2i[]"> </return> <description> Returns a [Vector2] array with the positions of all cells containing a tile from the tileset (i.e. a tile index different from [code]-1[/code]). </description> </method> <method name="get_used_cells_by_id" qualifiers="const"> - <return type="Array"> + <return type="Vector2i[]"> </return> <argument index="0" name="id" type="int"> </argument> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index e4d367c344..4175f01eb4 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -135,7 +135,7 @@ <argument index="0" name="scale" type="Vector3"> </argument> <description> - Scales the transform by the given scale factor, using matrix multiplication. + Scales basis and origin of the transform by the given scale factor, using matrix multiplication. </description> </method> <method name="translated"> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index b01ba3850f..0b2fb80480 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -16,7 +16,7 @@ var subchild1 = tree.create_item(child1) subchild1.set_text(0, "Subchild1") [/codeblock] - To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root]. + To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root]. You can use [method Object.free] on a [TreeItem] to remove it from the [Tree]. </description> <tutorials> </tutorials> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 84aa3a3686..a8a17370c2 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -5,6 +5,7 @@ </brief_description> <description> Control for a single item inside a [Tree]. May have child [TreeItem]s and be styled as well as contain buttons. + You can remove a [TreeItem] by using [method Object.free]. </description> <tutorials> </tutorials> @@ -350,7 +351,7 @@ <argument index="0" name="child" type="Object"> </argument> <description> - Removes the given child TreeItem. + Removes the given child [TreeItem] and all its children from the [Tree]. Note that it doesn't free the item from memory, so it can be reused later. To completely remove a [TreeItem] use [method Object.free]. </description> </method> <method name="select"> diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index 371b027534..f9320ac55e 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -6,7 +6,7 @@ <description> Tweens are useful for animations requiring a numerical property to be interpolated over a range of values. The name [i]tween[/i] comes from [i]in-betweening[/i], an animation technique where you specify [i]keyframes[/i] and the computer interpolates the frames that appear between them. [Tween] is more suited than [AnimationPlayer] for animations where you don't know the final values in advance. For example, interpolating a dynamically-chosen camera zoom value is best done with a [Tween] node; it would be difficult to do the same thing with an [AnimationPlayer] node. - Here is a brief usage example that causes a 2D node to move smoothly between two positions: + Here is a brief usage example that makes a 2D node move smoothly between two positions: [codeblock] var tween = get_node("Tween") tween.interpolate_property($Node2D, "position", @@ -15,7 +15,8 @@ tween.start() [/codeblock] Many methods require a property name, such as [code]"position"[/code] above. You can find the correct property name by hovering over the property in the Inspector. You can also provide the components of a property directly by using [code]"property:component"[/code] (eg. [code]position:x[/code]), where it would only apply to that particular component. - Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [code]http://easings.net/[/code] for some examples). The second accepts an [enum EaseType] constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best. + Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best. + [b][url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url][/b] </description> <tutorials> </tutorials> diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml index 3faafdfe80..9394d6b430 100644 --- a/doc/classes/VSlider.xml +++ b/doc/classes/VSlider.xml @@ -23,6 +23,8 @@ <theme_item name="grabber_area" type="StyleBox"> The background of the area below the grabber. </theme_item> + <theme_item name="grabber_area_highlight" type="StyleBox"> + </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> The texture for the grabber when it's disabled. </theme_item> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 5826822c6e..a2d53f8e0c 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -192,8 +192,10 @@ If [code]true[/code], the viewport will process 3D audio streams. </member> <member name="canvas_item_default_texture_filter" type="int" setter="set_default_canvas_item_texture_filter" getter="get_default_canvas_item_texture_filter" enum="Viewport.DefaultCanvasItemTextureFilter" default="1"> + Sets the default filter mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureFilter] for options. </member> <member name="canvas_item_default_texture_repeat" type="int" setter="set_default_canvas_item_texture_repeat" getter="get_default_canvas_item_texture_repeat" enum="Viewport.DefaultCanvasItemTextureRepeat" default="0"> + Sets the default repeat mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureRepeat] for options. </member> <member name="canvas_transform" type="Transform2D" setter="set_canvas_transform" getter="get_canvas_transform"> The canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]s. This is relative to the global canvas transform of the viewport. @@ -223,6 +225,9 @@ <member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false"> If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process. </member> + <member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0"> + Sets the screen-space antialiasing method used. 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. + </member> <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2"> The subdivision amount of the first quadrant on the shadow atlas. </member> @@ -288,6 +293,33 @@ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="ShadowAtlasQuadrantSubdiv"> Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum. </constant> + <constant name="MSAA_DISABLED" value="0" enum="MSAA"> + Multisample antialiasing mode disabled. This is the default value, and also the fastest setting. + </constant> + <constant name="MSAA_2X" value="1" enum="MSAA"> + Use 2x Multisample Antialiasing. + </constant> + <constant name="MSAA_4X" value="2" enum="MSAA"> + Use 4x Multisample Antialiasing. + </constant> + <constant name="MSAA_8X" value="3" enum="MSAA"> + Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware. + </constant> + <constant name="MSAA_16X" value="4" enum="MSAA"> + Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware. + </constant> + <constant name="MSAA_MAX" value="5" enum="MSAA"> + Represents the size of the [enum MSAA] enum. + </constant> + <constant name="SCREEN_SPACE_AA_DISABLED" value="0" enum="ScreenSpaceAA"> + Do not perform any antialiasing in the full screen post-process. + </constant> + <constant name="SCREEN_SPACE_AA_FXAA" value="1" enum="ScreenSpaceAA"> + Use fast approximate antialiasing. FXAA is a popular screen-space antialising method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K. + </constant> + <constant name="SCREEN_SPACE_AA_MAX" value="2" enum="ScreenSpaceAA"> + Represents the size of the [enum ScreenSpaceAA] enum. + </constant> <constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> Amount of objects in frame. </constant> @@ -315,58 +347,71 @@ <constant name="DEBUG_DRAW_UNSHADED" value="1" enum="DebugDraw"> Objects are displayed without light information. </constant> + <constant name="DEBUG_DRAW_LIGHTING" value="2" enum="DebugDraw"> + </constant> <constant name="DEBUG_DRAW_OVERDRAW" value="3" enum="DebugDraw"> - Objected are displayed semi-transparent with additive blending so you can see where they intersect. + Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others. </constant> <constant name="DEBUG_DRAW_WIREFRAME" value="4" enum="DebugDraw"> Objects are displayed in wireframe style. </constant> + <constant name="DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="DebugDraw"> + </constant> <constant name="DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="DebugDraw"> + Objects are displayed with only the albedo value from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="DebugDraw"> + Objects are displayed with only the lighting value from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="DebugDraw"> + Objects are displayed with only the emission color from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="DebugDraw"> + Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="DebugDraw"> + Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="DebugDraw"> </constant> <constant name="DEBUG_DRAW_SSAO" value="12" enum="DebugDraw"> + Draws the screen-space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> - <constant name="MSAA_DISABLED" value="0" enum="MSAA"> - Multisample anti-aliasing mode disabled. This is the default value. - </constant> - <constant name="MSAA_2X" value="1" enum="MSAA"> - Use 2x Multisample Antialiasing. - </constant> - <constant name="MSAA_4X" value="2" enum="MSAA"> - Use 4x Multisample Antialiasing. + <constant name="DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="DebugDraw"> + Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. </constant> - <constant name="MSAA_8X" value="3" enum="MSAA"> - Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware. + <constant name="DEBUG_DRAW_PSSM_SPLITS" value="14" enum="DebugDraw"> + Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order, they will be colored red, green, blue, and yellow. </constant> - <constant name="MSAA_16X" value="4" enum="MSAA"> - Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware. + <constant name="DEBUG_DRAW_DECAL_ATLAS" value="15" enum="DebugDraw"> + Draws the decal atlas used by [Decal]s and light projector textures in the upper left quadrant of the [Viewport]. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="1" enum="DefaultCanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="2" enum="DefaultCanvasItemTextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="DefaultCanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX" value="4" enum="DefaultCanvasItemTextureFilter"> + Max value for [enum DefaultCanvasItemTextureFilter] enum. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="0" enum="DefaultCanvasItemTextureRepeat"> + Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="1" enum="DefaultCanvasItemTextureRepeat"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="2" enum="DefaultCanvasItemTextureRepeat"> + Flip the texture when repeating so that the edge lines up instead of abruptly changing. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="3" enum="DefaultCanvasItemTextureRepeat"> + Max value for [enum DefaultCanvasItemTextureRepeat] enum. </constant> </constants> </class> diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml index 0bdecafbfa..a5abf16a8d 100644 --- a/doc/classes/VisibilityEnabler2D.xml +++ b/doc/classes/VisibilityEnabler2D.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" version="4.0"> <brief_description> - Enables certain nodes only when visible. + Enables certain nodes only when approximately visible. </brief_description> <description> The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and other nodes when they are not visible. It will only affect nodes with the same root node as the VisibilityEnabler2D, and the root node itself. - Note that VisibilityEnabler2D will not affect nodes added after scene initialization. + [b]Note:[/b] For performance reasons, VisibilityEnabler2D uses an approximate heuristic with precision determined by [member ProjectSettings.world/2d/cell_size]. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node. + [b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene initialization. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityEnabler3D.xml b/doc/classes/VisibilityEnabler3D.xml index 9c25c6c7c8..342a37e7a4 100644 --- a/doc/classes/VisibilityEnabler3D.xml +++ b/doc/classes/VisibilityEnabler3D.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityEnabler3D" inherits="VisibilityNotifier3D" version="4.0"> <brief_description> - Enables certain nodes only when visible. + Enables certain nodes only when approximately visible. </brief_description> <description> The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] nodes when they are not visible. It will only affect other nodes within the same scene as the VisibilityEnabler3D itself. - Note that VisibilityEnabler3D will not affect nodes added after scene initialization. + [b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node. + [b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene initialization. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml index f2a4a59d77..391163ef94 100644 --- a/doc/classes/VisibilityNotifier2D.xml +++ b/doc/classes/VisibilityNotifier2D.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityNotifier2D" inherits="Node2D" version="4.0"> <brief_description> - Detects when the node is visible on screen. + Detects approximately when the node is visible on screen. </brief_description> <description> The VisibilityNotifier2D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a viewport. + [b]Note:[/b] For performance reasons, VisibilityNotifier2D uses an approximate heuristic with precision determined by [member ProjectSettings.world/2d/cell_size]. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityNotifier3D.xml b/doc/classes/VisibilityNotifier3D.xml index d8a605c69c..eb7bb91f26 100644 --- a/doc/classes/VisibilityNotifier3D.xml +++ b/doc/classes/VisibilityNotifier3D.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityNotifier3D" inherits="Node3D" version="4.0"> <brief_description> - Detects when the node is visible on screen. + Detects approximately when the node is visible on screen. </brief_description> <description> The VisibilityNotifier3D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a [Camera3D]'s view. + [b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node. </description> <tutorials> </tutorials> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index c6c6cae6c0..5ceab52523 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -973,11 +973,14 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl f.write("\n") -def make_type(t, state): # type: (str, State) -> str - if t in state.classes: - return ":ref:`{0}<class_{0}>`".format(t) - print_error("Unresolved type '{}', file: {}".format(t, state.current_class), state) - return t +def make_type(klass, state): # type: (str, State) -> str + link_type = klass + if link_type.endswith("[]"): # Typed array, strip [] to link to contained type. + link_type = link_type[:-2] + if link_type in state.classes: + return ":ref:`{}<class_{}>`".format(klass, link_type) + print_error("Unresolved type '{}', file: {}".format(klass, state.current_class), state) + return klass def make_enum(t, state): # type: (str, State) -> str diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp index 95876f5c7d..ddd2943720 100644 --- a/drivers/dummy/texture_loader_dummy.cpp +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -35,7 +35,7 @@ #include <string.h> -RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { unsigned int width = 8; unsigned int height = 8; @@ -67,10 +67,19 @@ RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_origi } void ResourceFormatDummyTexture::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("png"); - p_extensions->push_back("hdr"); + p_extensions->push_back("bmp"); + p_extensions->push_back("dds"); + p_extensions->push_back("exr"); + p_extensions->push_back("jpeg"); p_extensions->push_back("jpg"); + p_extensions->push_back("hdr"); + p_extensions->push_back("pkm"); + p_extensions->push_back("png"); + p_extensions->push_back("pvr"); + p_extensions->push_back("svg"); + p_extensions->push_back("svgz"); p_extensions->push_back("tga"); + p_extensions->push_back("webp"); } bool ResourceFormatDummyTexture::handles_type(const String &p_type) const { @@ -79,7 +88,22 @@ bool ResourceFormatDummyTexture::handles_type(const String &p_type) const { String ResourceFormatDummyTexture::get_resource_type(const String &p_path) const { String extension = p_path.get_extension().to_lower(); - if (extension == "png" || extension == "hdr" || extension == "jpg" || extension == "tga") + if ( + extension == "bmp" || + extension == "dds" || + extension == "exr" || + extension == "jpeg" || + extension == "jpg" || + extension == "hdr" || + extension == "pkm" || + extension == "png" || + extension == "pvr" || + extension == "svg" || + extension == "svgz" || + extension == "tga" || + extension == "webp") { return "ImageTexture"; + } + return ""; } diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h index 2a7d01dd78..ef9f3b13b6 100644 --- a/drivers/dummy/texture_loader_dummy.h +++ b/drivers/dummy/texture_loader_dummy.h @@ -36,7 +36,7 @@ class ResourceFormatDummyTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 2ba2147de9..bdf0559f58 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -4045,7 +4045,7 @@ void RasterizerSceneGLES2::initialize() { //maximum compatibility, renderbuffer and RGBA shadow glGenRenderbuffers(1, &directional_shadow.depth); glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth); - glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size); + glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, directional_shadow.size, directional_shadow.size); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth); glGenTextures(1, &directional_shadow.color); diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 2769469838..23e9227a39 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -3327,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec } // 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 -RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) { +RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) { _THREAD_SAFE_METHOD_ @@ -3402,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo //validate with buffer { - const VertexDescription &atf = vd.vertex_formats[i]; + const VertexAttribute &atf = vd.vertex_formats[i]; uint32_t element_size = get_format_vertex_size(atf.format); ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated @@ -5085,29 +5085,29 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma depth_stencil_state_create_info.depthBoundsTestEnable = p_depth_stencil_state.enable_depth_range; depth_stencil_state_create_info.stencilTestEnable = p_depth_stencil_state.enable_stencil; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.pass, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.pass]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.depth_fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.depth_fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.compare, COMPARE_OP_MAX, RID()); - depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_front.compare]; - depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.stencil_operation_front.compare_mask; - depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.stencil_operation_front.write_mask; - depth_stencil_state_create_info.front.reference = p_depth_stencil_state.stencil_operation_front.reference; - - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.pass, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.pass]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.depth_fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.depth_fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.compare, COMPARE_OP_MAX, RID()); - depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_back.compare]; - depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.stencil_operation_back.compare_mask; - depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.stencil_operation_back.write_mask; - depth_stencil_state_create_info.back.reference = p_depth_stencil_state.stencil_operation_back.reference; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.front_op.fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.pass, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.front_op.pass]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.depth_fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.front_op.depth_fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.compare, COMPARE_OP_MAX, RID()); + depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.front_op.compare]; + depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.front_op.compare_mask; + depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.front_op.write_mask; + depth_stencil_state_create_info.front.reference = p_depth_stencil_state.front_op.reference; + + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.back_op.fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.pass, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.back_op.pass]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.depth_fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.back_op.depth_fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.compare, COMPARE_OP_MAX, RID()); + depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.back_op.compare]; + depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.back_op.compare_mask; + depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.back_op.write_mask; + depth_stencil_state_create_info.back.reference = p_depth_stencil_state.back_op.reference; depth_stencil_state_create_info.minDepthBounds = p_depth_stencil_state.depth_range_min; depth_stencil_state_create_info.maxDepthBounds = p_depth_stencil_state.depth_range_max; @@ -5336,17 +5336,19 @@ bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) { int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ - + ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_width(p_screen); } int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_height(p_screen); } RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); //very hacky, but not used often per frame so I guess ok VkFormat vkformat = context->get_screen_format(); @@ -5376,6 +5378,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); @@ -6040,7 +6043,7 @@ void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_ vkCmdSetLineWidth(dl->command_buffer, p_width); } -void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) { +void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); @@ -6443,7 +6446,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, #endif } -void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) { +void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6695,75 +6698,104 @@ void RenderingDeviceVulkan::free(RID p_id) { _free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems _free_internal(p_id); } -void RenderingDeviceVulkan::swap_buffers() { - _THREAD_SAFE_METHOD_ +void RenderingDeviceVulkan::_finalize_command_bufers() { - { //finalize frame + if (draw_list) { + ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); + } - if (draw_list) { - ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); - } + if (compute_list) { + ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); + } - if (compute_list) { - ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); - } + { //complete the setup buffer (that needs to be processed before anything else) + vkEndCommandBuffer(frames[frame].setup_command_buffer); + vkEndCommandBuffer(frames[frame].draw_command_buffer); + } +} + +void RenderingDeviceVulkan::_begin_frame() { + + //erase pending resources + _free_pending_resources(frame); + + //create setup command buffer and set as the setup buffer + + { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; + + VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); + ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + "."); + + err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - { //complete the setup buffer (that needs to be processed before anything else) - vkEndCommandBuffer(frames[frame].setup_command_buffer); - vkEndCommandBuffer(frames[frame].draw_command_buffer); + if (local_device.is_null()) { + context->append_command_buffer(frames[frame].draw_command_buffer); + context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else } - screen_prepared = false; } - //swap buffers - context->swap_buffers(); + //advance current frame + frames_drawn++; + //advance staging buffer if used + if (staging_buffer_used) { + staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); + staging_buffer_used = false; + } - { //advance frame + if (frames[frame].timestamp_count) { + vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); + SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); + SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); + } - frame = (frame + 1) % frame_count; + frames[frame].timestamp_result_count = frames[frame].timestamp_count; + frames[frame].timestamp_count = 0; + frames[frame].index = Engine::get_singleton()->get_frames_drawn(); +} - //erase pending resources - _free_pending_resources(frame); +void RenderingDeviceVulkan::swap_buffers() { - //create setup command buffer and set as the setup buffer + ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers."); + _THREAD_SAFE_METHOD_ - { - VkCommandBufferBeginInfo cmdbuf_begin; - cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdbuf_begin.pNext = nullptr; - cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cmdbuf_begin.pInheritanceInfo = nullptr; + _finalize_command_bufers(); - VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); - ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + "."); + screen_prepared = false; + //swap buffers + context->swap_buffers(); - err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else - err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[frame].draw_command_buffer); - } + frame = (frame + 1) % frame_count; - //advance current frame - frames_drawn++; - //advance staging buffer if used - if (staging_buffer_used) { - staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); - staging_buffer_used = false; - } + _begin_frame(); +} - if (frames[frame].timestamp_count) { - vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); - SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); - SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); - } +void RenderingDeviceVulkan::submit() { + ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync."); + ERR_FAIL_COND_MSG(local_device_processing, "device already submitted, call sync to wait until done."); - frames[frame].timestamp_result_count = frames[frame].timestamp_count; - frames[frame].timestamp_count = 0; - frames[frame].index = Engine::get_singleton()->get_frames_drawn(); - } + _finalize_command_bufers(); + + VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer }; + context->local_device_push_command_buffers(local_device, command_buffers, 2); + local_device_processing = true; +} + +void RenderingDeviceVulkan::sync() { + + ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync."); + ERR_FAIL_COND_MSG(!local_device_processing, "sync can only be called after a submit"); + + context->local_device_sync(local_device); + _begin_frame(); } void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { @@ -6882,14 +6914,21 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const { void RenderingDeviceVulkan::_flush(bool p_current_frame) { + if (local_device.is_valid() && !p_current_frame) { + return; //flushign previous frames has no effect with local device + } //not doing this crashes RADV (undefined behavior) if (p_current_frame) { vkEndCommandBuffer(frames[frame].setup_command_buffer); vkEndCommandBuffer(frames[frame].draw_command_buffer); } - context->flush(p_current_frame, p_current_frame); - //re-create the setup command - if (p_current_frame) { + + if (local_device.is_valid()) { + + VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer }; + context->local_device_push_command_buffers(local_device, command_buffers, 2); + context->local_device_sync(local_device); + VkCommandBufferBeginInfo cmdbuf_begin; cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmdbuf_begin.pNext = nullptr; @@ -6898,27 +6937,48 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) { VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else - } + err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - if (p_current_frame) { - VkCommandBufferBeginInfo cmdbuf_begin; - cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdbuf_begin.pNext = nullptr; - cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cmdbuf_begin.pInheritanceInfo = nullptr; + } else { + context->flush(p_current_frame, p_current_frame); + //re-create the setup command + if (p_current_frame) { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; - VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[frame].draw_command_buffer); + VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else + } + + if (p_current_frame) { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; + + VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + context->append_command_buffer(frames[frame].draw_command_buffer); + } } } -void RenderingDeviceVulkan::initialize(VulkanContext *p_context) { +void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) { context = p_context; device = p_context->get_device(); - frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this. + if (p_local_device) { + frame_count = 1; + local_device = p_context->local_device_create(); + } else { + frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this. + } limits = p_context->get_device_limits(); max_timestamp_query_elements = 256; @@ -6999,11 +7059,13 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context) { VkResult err = vkBeginCommandBuffer(frames[0].setup_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else err = vkBeginCommandBuffer(frames[0].draw_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[0].draw_command_buffer); + if (local_device.is_null()) { + context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else + context->append_command_buffer(frames[0].draw_command_buffer); + } } staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); @@ -7285,6 +7347,19 @@ void RenderingDeviceVulkan::finalize() { ERR_FAIL_COND(reverse_dependency_map.size()); } +RenderingDevice *RenderingDeviceVulkan::create_local_device() { + RenderingDeviceVulkan *rd = memnew(RenderingDeviceVulkan); + rd->initialize(context, true); + return rd; +} + RenderingDeviceVulkan::RenderingDeviceVulkan() { screen_prepared = false; } + +RenderingDeviceVulkan::~RenderingDeviceVulkan() { + if (local_device.is_valid()) { + finalize(); + context->local_device_free(local_device); + } +} diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 2c92f3466e..6432946fbe 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -332,7 +332,7 @@ class RenderingDeviceVulkan : public RenderingDevice { RID_Owner<Buffer, true> vertex_buffer_owner; struct VertexDescriptionKey { - Vector<VertexDescription> vertex_formats; + Vector<VertexAttribute> vertex_formats; bool operator==(const VertexDescriptionKey &p_key) const { int vdc = vertex_formats.size(); int vdck = p_key.vertex_formats.size(); @@ -340,11 +340,11 @@ class RenderingDeviceVulkan : public RenderingDevice { if (vdc != vdck) { return false; } else { - const VertexDescription *a_ptr = vertex_formats.ptr(); - const VertexDescription *b_ptr = p_key.vertex_formats.ptr(); + const VertexAttribute *a_ptr = vertex_formats.ptr(); + const VertexAttribute *b_ptr = p_key.vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &a = a_ptr[i]; - const VertexDescription &b = b_ptr[i]; + const VertexAttribute &a = a_ptr[i]; + const VertexAttribute &b = b_ptr[i]; if (a.location != b.location) { return false; @@ -369,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t hash() const { int vdc = vertex_formats.size(); uint32_t h = hash_djb2_one_32(vdc); - const VertexDescription *ptr = vertex_formats.ptr(); + const VertexAttribute *ptr = vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &vd = ptr[i]; + const VertexAttribute &vd = ptr[i]; h = hash_djb2_one_32(vd.location, h); h = hash_djb2_one_32(vd.offset, h); h = hash_djb2_one_32(vd.format, h); @@ -393,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice { HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache; struct VertexDescriptionCache { - Vector<VertexDescription> vertex_formats; + Vector<VertexAttribute> vertex_formats; VkVertexInputBindingDescription *bindings; VkVertexInputAttributeDescription *attributes; VkPipelineVertexInputStateCreateInfo create_info; @@ -952,10 +952,12 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t max_timestamp_query_elements; - Frame *frames; //frames available, they are cycled (usually 3) + Frame *frames; //frames available, for main device they are cycled (usually 3), for local devices only 1 int frame; //current frame int frame_count; //total amount of frames uint64_t frames_drawn; + RID local_device; + bool local_device_processing = false; void _free_pending_resources(int p_frame); @@ -971,6 +973,9 @@ class RenderingDeviceVulkan : public RenderingDevice { template <class T> void _free_rids(T &p_owner, const char *p_type); + void _finalize_command_bufers(); + void _begin_frame(); + public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()); virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); @@ -1011,7 +1016,7 @@ public: virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()); // 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 - virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats); + virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats); virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers); virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false); @@ -1075,7 +1080,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array); virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array); virtual void draw_list_set_line_width(DrawListID p_list, float p_width); - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size); + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size); virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0); @@ -1091,7 +1096,7 @@ public: virtual ComputeListID compute_list_begin(); virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline); virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index); - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size); + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size); virtual void compute_list_add_barrier(ComputeListID p_list); virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); @@ -1121,14 +1126,20 @@ public: virtual int limit_get(Limit p_limit); virtual void prepare_screen_for_drawing(); - void initialize(VulkanContext *p_context); + void initialize(VulkanContext *p_context, bool p_local_device = false); void finalize(); - virtual void swap_buffers(); + virtual void swap_buffers(); //for main device + + virtual void submit(); //for local device + virtual void sync(); //for local device virtual uint32_t get_frame_delay() const; + virtual RenderingDevice *create_local_device(); + RenderingDeviceVulkan(); + ~RenderingDeviceVulkan(); }; #endif // RENDERING_DEVICE_VULKAN_H diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 0ce9ccce4c..d293abdee3 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -165,16 +165,17 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n Error VulkanContext::_create_validation_layers() { VkResult err; + const char *instance_validation_layers_alt1[] = { "VK_LAYER_KHRONOS_validation" }; + const char *instance_validation_layers_alt2[] = { "VK_LAYER_LUNARG_standard_validation" }; + const char *instance_validation_layers_alt3[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" }; + uint32_t instance_layer_count = 0; - uint32_t validation_layer_count = 0; - const char *instance_validation_layers_alt1[] = { "VK_LAYER_LUNARG_standard_validation" }; - const char *instance_validation_layers_alt2[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", - "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", - "VK_LAYER_GOOGLE_unique_objects" }; - VkBool32 validation_found = 0; err = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); - const char **instance_validation_layers = instance_validation_layers_alt1; + + VkBool32 validation_found = 0; + uint32_t validation_layer_count = 0; + const char **instance_validation_layers = nullptr; if (instance_layer_count > 0) { VkLayerProperties *instance_layers = (VkLayerProperties *)malloc(sizeof(VkLayerProperties) * instance_layer_count); err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers); @@ -183,27 +184,33 @@ Error VulkanContext::_create_validation_layers() { ERR_FAIL_V(ERR_CANT_CREATE); } - validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt1), instance_validation_layers, - instance_layer_count, instance_layers); - if (validation_found) { - enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1); - enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation"; - validation_layer_count = 1; - } else { - // use alternative set of validation layers - instance_validation_layers = instance_validation_layers_alt2; - enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt2); - validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt2), instance_validation_layers, - instance_layer_count, instance_layers); + validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt1); + instance_validation_layers = instance_validation_layers_alt1; + validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers); + + // use alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers + if (!validation_found) { validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt2); - for (uint32_t i = 0; i < validation_layer_count; i++) { - enabled_layers[i] = instance_validation_layers[i]; - } + instance_validation_layers = instance_validation_layers_alt2; + validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers); + } + + // use alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers + if (!validation_found) { + validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt3); + instance_validation_layers = instance_validation_layers_alt3; + validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers); } + free(instance_layers); } - if (!validation_found) { + if (validation_found) { + enabled_layer_count = validation_layer_count; + for (uint32_t i = 0; i < validation_layer_count; i++) { + enabled_layers[i] = instance_validation_layers[i]; + } + } else { return ERR_CANT_CREATE; } @@ -1499,6 +1506,87 @@ VulkanContext::VulkanContext() { swapchainImageCount = 0; } +RID VulkanContext::local_device_create() { + LocalDevice ld; + + { //create device + VkResult err; + float queue_priorities[1] = { 0.0 }; + VkDeviceQueueCreateInfo queues[2]; + queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queues[0].pNext = nullptr; + queues[0].queueFamilyIndex = graphics_queue_family_index; + queues[0].queueCount = 1; + queues[0].pQueuePriorities = queue_priorities; + queues[0].flags = 0; + + VkDeviceCreateInfo sdevice = { + /*sType =*/VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + /*pNext */ nullptr, + /*flags */ 0, + /*queueCreateInfoCount */ 1, + /*pQueueCreateInfos */ queues, + /*enabledLayerCount */ 0, + /*ppEnabledLayerNames */ nullptr, + /*enabledExtensionCount */ enabled_extension_count, + /*ppEnabledExtensionNames */ (const char *const *)extension_names, + /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here + }; + err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device); + ERR_FAIL_COND_V(err, RID()); + } + + { //create graphics queue + + vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue); + } + + return local_device_owner.make_rid(ld); +} + +VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) { + LocalDevice *ld = local_device_owner.getornull(p_local_device); + return ld->device; +} + +void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + ERR_FAIL_COND(ld->waiting); + + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.pWaitDstStageMask = nullptr; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = nullptr; + submit_info.commandBufferCount = p_count; + submit_info.pCommandBuffers = p_buffers; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = nullptr; + + VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE); + ERR_FAIL_COND(err); + + ld->waiting = true; +} + +void VulkanContext::local_device_sync(RID p_local_device) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + ERR_FAIL_COND(!ld->waiting); + + vkDeviceWaitIdle(ld->device); + ld->waiting = false; +} + +void VulkanContext::local_device_free(RID p_local_device) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + vkDestroyDevice(ld->device, nullptr); + local_device_owner.free(p_local_device); +} + VulkanContext::~VulkanContext() { if (queue_props) { free(queue_props); diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index e587104e3c..51c3febb47 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -33,6 +33,8 @@ #include "core/error_list.h" #include "core/map.h" +#include "core/os/mutex.h" +#include "core/rid_owner.h" #include "core/ustring.h" #include "servers/display_server.h" #include <vulkan/vulkan.h> @@ -105,6 +107,14 @@ class VulkanContext { } }; + struct LocalDevice { + bool waiting = false; + VkDevice device; + VkQueue queue; + }; + + RID_Owner<LocalDevice, true> local_device_owner; + Map<DisplayServer::WindowID, Window> windows; uint32_t swapchainImageCount; @@ -194,6 +204,12 @@ public: VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0); VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0); + RID local_device_create(); + VkDevice local_device_get_vk_device(RID p_local_device); + void local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count); + void local_device_sync(RID p_local_device); + void local_device_free(RID p_local_device); + VkFormat get_screen_format() const; VkPhysicalDeviceLimits get_device_limits() const; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index f10e439f10..09f55bea0c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -31,7 +31,7 @@ #include "animation_track_editor.h" #include "animation_track_editor_plugins.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "editor/animation_bezier_editor.h" #include "editor/plugins/animation_player_editor_plugin.h" @@ -754,14 +754,17 @@ public: for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { + int key = 0; for (List<float>::Element *F = E->value().front(); F; F = F->next()) { float key_ofs = F->get(); - if (from != key_ofs) + if (from != key_ofs) { + key++; continue; + } int track = E->key(); - key_ofs_map[track][key_ofs] = to; + key_ofs_map[track][key] = to; if (setting) return; @@ -4100,7 +4103,7 @@ bool AnimationTrackEditor::is_selection_active() const { } bool AnimationTrackEditor::is_snap_enabled() const { - return snap->is_pressed() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); } void AnimationTrackEditor::_update_tracks() { diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 77e20b971c..987d5649b1 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -30,7 +30,7 @@ #include "code_editor.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/string_builder.h" #include "editor/editor_scale.h" @@ -513,7 +513,7 @@ void FindReplaceBar::_search_text_changed(const String &p_text) { void FindReplaceBar::_search_text_entered(const String &p_text) { - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { search_prev(); } else { search_next(); @@ -525,7 +525,7 @@ void FindReplaceBar::_replace_text_entered(const String &p_text) { if (selection_only->is_pressed() && text_edit->is_selection_active()) { _replace_all(); _hide_bar(); - } else if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + } else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { _replace(); search_prev(); } else { diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 1971abadc4..81a7d85b18 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -149,39 +149,74 @@ void ScriptEditorDebugger::save_node(ObjectID p_id, const String &p_file) { } void ScriptEditorDebugger::_file_selected(const String &p_file) { - Error err; - FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err); - if (err != OK) { - ERR_PRINT("Failed to open " + p_file); - return; - } - Vector<String> line; - line.resize(Performance::MONITOR_MAX); + switch (file_dialog_purpose) { + case SAVE_MONITORS_CSV: { + Error err; + FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err); - // signatures - for (int i = 0; i < Performance::MONITOR_MAX; i++) { - line.write[i] = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)); - } - file->store_csv_line(line); + if (err != OK) { + ERR_PRINT("Failed to open " + p_file); + return; + } + Vector<String> line; + line.resize(Performance::MONITOR_MAX); - // values - List<Vector<float>>::Element *E = perf_history.back(); - while (E) { + // signatures + for (int i = 0; i < Performance::MONITOR_MAX; i++) { + line.write[i] = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i)); + } + file->store_csv_line(line); - Vector<float> &perf_data = E->get(); - for (int i = 0; i < perf_data.size(); i++) { + // values + List<Vector<float>>::Element *E = perf_history.back(); + while (E) { - line.write[i] = String::num_real(perf_data[i]); - } - file->store_csv_line(line); - E = E->prev(); - } - file->store_string("\n"); + Vector<float> &perf_data = E->get(); + for (int i = 0; i < perf_data.size(); i++) { + + line.write[i] = String::num_real(perf_data[i]); + } + file->store_csv_line(line); + E = E->prev(); + } + file->store_string("\n"); + + Vector<Vector<String>> profiler_data = profiler->get_data_as_csv(); + for (int i = 0; i < profiler_data.size(); i++) { + file->store_csv_line(profiler_data[i]); + } + } break; + case SAVE_VRAM_CSV: { + Error err; + FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err); - Vector<Vector<String>> profiler_data = profiler->get_data_as_csv(); - for (int i = 0; i < profiler_data.size(); i++) { - file->store_csv_line(profiler_data[i]); + if (err != OK) { + ERR_PRINT("Failed to open " + p_file); + return; + } + + Vector<String> headers; + headers.resize(vmem_tree->get_columns()); + for (int i = 0; i < vmem_tree->get_columns(); ++i) { + headers.write[i] = vmem_tree->get_column_title(i); + } + file->store_csv_line(headers); + + if (vmem_tree->get_root()) { + TreeItem *ti = vmem_tree->get_root()->get_children(); + while (ti) { + Vector<String> values; + values.resize(vmem_tree->get_columns()); + for (int i = 0; i < vmem_tree->get_columns(); ++i) { + values.write[i] = ti->get_text(i); + } + file->store_csv_line(values); + + ti = ti->get_next(); + } + } + } break; } } @@ -233,6 +268,15 @@ void ScriptEditorDebugger::_video_mem_request() { _put_msg("core:memory", Array()); } +void ScriptEditorDebugger::_video_mem_export() { + + file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); + file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog->clear_filters(); + file_dialog_purpose = SAVE_VRAM_CSV; + file_dialog->popup_centered_ratio(); +} + Size2 ScriptEditorDebugger::get_minimum_size() const { Size2 ms = MarginContainer::get_minimum_size(); @@ -766,6 +810,7 @@ void ScriptEditorDebugger::_notification(int p_what) { error_tree->connect("item_selected", callable_mp(this, &ScriptEditorDebugger::_error_selected)); error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated)); vmem_refresh->set_icon(get_theme_icon("Reload", "EditorIcons")); + vmem_export->set_icon(get_theme_icon("Save", "EditorIcons")); reason->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); @@ -840,6 +885,7 @@ void ScriptEditorDebugger::_notification(int p_what) { dobreak->set_icon(get_theme_icon("Pause", "EditorIcons")); docontinue->set_icon(get_theme_icon("DebugContinue", "EditorIcons")); vmem_refresh->set_icon(get_theme_icon("Reload", "EditorIcons")); + vmem_export->set_icon(get_theme_icon("Save", "EditorIcons")); } break; } } @@ -981,6 +1027,7 @@ void ScriptEditorDebugger::_export_csv() { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog_purpose = SAVE_MONITORS_CSV; file_dialog->popup_centered_ratio(); } @@ -1701,8 +1748,12 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { vmem_hb->add_child(vmem_total); vmem_refresh = memnew(ToolButton); vmem_hb->add_child(vmem_refresh); + vmem_export = memnew(ToolButton); + vmem_export->set_tooltip(TTR("Export list to a CSV file")); + vmem_hb->add_child(vmem_export); vmem_vb->add_child(vmem_hb); vmem_refresh->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_video_mem_request)); + vmem_export->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_video_mem_export)); VBoxContainer *vmmc = memnew(VBoxContainer); vmem_tree = memnew(Tree); diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index 9cb7dc2edf..a08a7c67c2 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -88,6 +88,11 @@ private: PopupMenu *item_menu; EditorFileDialog *file_dialog; + enum FileDialogPurpose { + SAVE_MONITORS_CSV, + SAVE_VRAM_CSV, + }; + FileDialogPurpose file_dialog_purpose; int error_count; int warning_count; @@ -121,6 +126,7 @@ private: Tree *vmem_tree; Button *vmem_refresh; + Button *vmem_export; LineEdit *vmem_total; Tree *stack_dump; @@ -160,6 +166,7 @@ private: void _remote_object_property_updated(ObjectID p_id, const String &p_property); void _video_mem_request(); + void _video_mem_export(); int _get_node_path_cache(const NodePath &p_path); diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp index 096be1fe4b..310e78ee60 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_data.cpp @@ -40,6 +40,9 @@ #include "core/version.h" #include "scene/resources/theme.h" +// Used for a hack preserving Mono properties on non-Mono builds. +#include "modules/modules_enabled.gen.h" + void DocData::merge_from(const DocData &p_data) { for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { @@ -154,6 +157,23 @@ void DocData::merge_from(const DocData &p_data) { break; } } + +#ifndef MODULE_MONO_ENABLED + // The Mono module defines some properties that we want to keep when + // re-generating docs with a non-Mono build, to prevent pointless diffs + // (and loss of descriptions) depending on the config of the doc writer. + // We use a horrible hack to force keeping the relevant properties, + // hardcoded below. At least it's an ad hoc hack... ¯\_(ツ)_/¯ + // Don't show this to your kids. + if (c.name == "@GlobalScope") { + // Retrieve GodotSharp singleton. + for (int j = 0; j < cf.properties.size(); j++) { + if (cf.properties[j].name == "GodotSharp") { + c.properties.push_back(cf.properties[j]); + } + } + } +#endif } } @@ -173,6 +193,8 @@ static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const Property p_method.return_type = "int"; } else if (p_retinfo.class_name != StringName()) { p_method.return_type = p_retinfo.class_name; + } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_method.return_type = p_retinfo.hint_string + "[]"; } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { p_method.return_type = p_retinfo.hint_string; } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { @@ -195,6 +217,8 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr p_argument.type = "int"; } else if (p_arginfo.class_name != StringName()) { p_argument.type = p_arginfo.class_name; + } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_argument.type = p_arginfo.hint_string + "[]"; } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { p_argument.type = p_arginfo.hint_string; } else if (p_arginfo.type == Variant::NIL) { @@ -243,6 +267,12 @@ void DocData::generate(bool p_basic_types) { Set<StringName> setters_getters; String name = classes.front()->get(); + if (!ClassDB::is_class_exposed(name)) { + print_verbose(vformat("Class '%s' is not exposed, skipping.", name)); + classes.pop_front(); + continue; + } + String cname = name; if (cname.begins_with("_")) //proxy class cname = cname.substr(1, name.length()); @@ -271,7 +301,7 @@ void DocData::generate(bool p_basic_types) { EO = EO->next(); } - if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) + if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) continue; PropertyDoc prop; @@ -328,6 +358,8 @@ void DocData::generate(bool p_basic_types) { prop.type = "int"; } else if (retinfo.class_name != StringName()) { prop.type = retinfo.class_name; + } else if (retinfo.type == Variant::ARRAY && retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + prop.type = retinfo.hint_string + "[]"; } else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { prop.type = retinfo.hint_string; diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 7e499facd5..c80ae5f21b 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -30,7 +30,7 @@ #include "editor_audio_buses.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" #include "editor_node.h" @@ -325,7 +325,7 @@ void EditorAudioBus::_volume_changed(float p_normalized) { const float p_db = this->_normalized_volume_to_scaled_db(p_normalized); - if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { // Snap the value when holding Ctrl for easier editing. // To do so, it needs to be converted back to normalized volume (as the slider uses that unit). slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db))); @@ -386,7 +386,7 @@ float EditorAudioBus::_scaled_db_to_normalized_volume(float db) { void EditorAudioBus::_show_value(float slider_value) { float db; - if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { // Display the correct (snapped) value when holding Ctrl db = Math::round(_normalized_volume_to_scaled_db(slider_value)); } else { diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 942b4a8ee6..9c739474d1 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() { return ret; } -Array EditorSelection::get_selected_nodes() { +TypedArray<Node> EditorSelection::get_selected_nodes() { - Array ret; + TypedArray<Node> ret; for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { diff --git a/editor/editor_data.h b/editor/editor_data.h index 4f5d68bfed..e4f4c67c8e 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -257,7 +257,7 @@ protected: static void _bind_methods(); public: - Array get_selected_nodes(); + TypedArray<Node> get_selected_nodes(); void add_node(Node *p_node); void remove_node(Node *p_node); bool is_selected(Node *) const; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index a36e2f360e..050b0a5f33 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -30,7 +30,7 @@ #include "editor_help.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "doc_data_compressed.gen.h" #include "editor/plugins/script_editor_plugin.h" @@ -198,7 +198,12 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) { const Color text_color = get_theme_color("default_color", "RichTextLabel"); const Color type_color = get_theme_color("accent_color", "Editor").linear_interpolate(text_color, 0.5); class_desc->push_color(type_color); + bool add_array = false; if (can_ref) { + if (t.ends_with("[]")) { + add_array = true; + t = t.replace("[]", ""); + } if (p_enum.empty()) { class_desc->push_meta("#" + t); //class } else { @@ -206,8 +211,15 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) { } } class_desc->add_text(t); - if (can_ref) + if (can_ref) { class_desc->pop(); + if (add_array) { + class_desc->add_text(" "); + class_desc->push_meta("#Array"); //class + class_desc->add_text("[]"); + class_desc->pop(); + } + } class_desc->pop(); } @@ -1832,7 +1844,7 @@ void FindBar::_search_text_changed(const String &p_text) { void FindBar::_search_text_entered(const String &p_text) { - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { search_prev(); } else { search_next(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index fddc5dc231..ea2009ab58 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -32,7 +32,7 @@ #include "core/bind/core_bind.h" #include "core/class_db.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/config_file.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -64,6 +64,7 @@ #include "servers/navigation_server_2d.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" +#include "servers/rendering/rendering_device.h" #include "editor/audio_stream_preview.h" #include "editor/debugger/editor_debugger_node.h" @@ -97,6 +98,7 @@ #include "editor/import/resource_importer_layered_texture.h" #include "editor/import/resource_importer_obj.h" #include "editor/import/resource_importer_scene.h" +#include "editor/import/resource_importer_shader_file.h" #include "editor/import/resource_importer_texture.h" #include "editor/import/resource_importer_texture_atlas.h" #include "editor/import/resource_importer_wav.h" @@ -147,6 +149,7 @@ #include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_text_editor.h" #include "editor/plugins/shader_editor_plugin.h" +#include "editor/plugins/shader_file_editor_plugin.h" #include "editor/plugins/skeleton_2d_editor_plugin.h" #include "editor/plugins/skeleton_3d_editor_plugin.h" #include "editor/plugins/skeleton_ik_3d_editor_plugin.h" @@ -1192,8 +1195,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { } img->convert(Image::FORMAT_RGB8); - img->flip_y(); - //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text(); @@ -2363,7 +2364,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case EDIT_UNDO: { - if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) { + if (Input::get_singleton()->get_mouse_button_mask() & 0x7) { log->add_message("Can't undo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR); } else { String action = editor_data.get_undo_redo().get_current_action_name(); @@ -2377,7 +2378,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case EDIT_REDO: { - if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) { + if (Input::get_singleton()->get_mouse_button_mask() & 0x7) { log->add_message("Can't redo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR); } else { if (!editor_data.get_undo_redo().redo()) { @@ -5563,7 +5564,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p EditorNode::EditorNode() { - InputFilter::get_singleton()->set_use_accumulated_input(true); + Input::get_singleton()->set_use_accumulated_input(true); Resource::_get_local_scene_func = _resource_get_edited_scene; RenderingServer::get_singleton()->set_debug_generate_wireframes(true); @@ -5579,7 +5580,7 @@ EditorNode::EditorNode() { ResourceLoader::clear_translation_remaps(); //no remaps using during editor ResourceLoader::clear_path_remaps(); - InputFilter *id = InputFilter::get_singleton(); + Input *id = Input::get_singleton(); if (id) { @@ -5590,7 +5591,7 @@ EditorNode::EditorNode() { } } - if (!found_touchscreen && InputFilter::get_singleton()) { + if (!found_touchscreen && Input::get_singleton()) { //only if no touchscreen ui hint, set emulation id->set_emulate_touch_from_mouse(false); //just disable just in case } @@ -5715,6 +5716,10 @@ EditorNode::EditorNode() { import_obj.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_obj); + Ref<ResourceImporterShaderFile> import_shader_file; + import_shader_file.instance(); + ResourceFormatImporter::get_singleton()->add_importer(import_shader_file); + Ref<ResourceImporterScene> import_scene; import_scene.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_scene); @@ -6632,6 +6637,7 @@ EditorNode::EditorNode() { add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin(this))); + add_editor_plugin(memnew(ShaderFileEditorPlugin(this))); add_editor_plugin(memnew(VisualShaderEditorPlugin(this))); add_editor_plugin(memnew(Camera3DEditorPlugin(this))); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5d5bb1242d..9b58c18f51 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -559,6 +559,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); // 3D: Freelook + _initial_set("editors/3d/freelook/freelook_navigation_scheme", false); + hints["editors/3d/freelook/freelook_navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_navigation_scheme", PROPERTY_HINT_ENUM, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)"); _initial_set("editors/3d/freelook/freelook_inertia", 0.1); hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); _initial_set("editors/3d/freelook/freelook_base_speed", 5.0); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 4eefe844d2..1506c574dd 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -30,7 +30,7 @@ #include "editor_spin_slider.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/expression.h" #include "editor_node.h" #include "editor_scale.h" @@ -68,7 +68,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { grabbing_spinner_dist_cache = 0; pre_grab_value = get_value(); grabbing_spinner = false; - grabbing_spinner_mouse_pos = InputFilter::get_singleton()->get_mouse_position(); + grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position(); } } else { @@ -76,8 +76,8 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { if (grabbing_spinner) { - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); - InputFilter::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos); update(); } else { _focus_entered(); @@ -106,7 +106,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { grabbing_spinner_dist_cache += diff_x; if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * EDSCALE) { - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); grabbing_spinner = true; } @@ -181,7 +181,7 @@ void EditorSpinSlider::_notification(int p_what) { p_what == NOTIFICATION_WM_FOCUS_IN || p_what == NOTIFICATION_EXIT_TREE) { if (grabbing_spinner) { - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); grabbing_spinner = false; grabbing_spinner_attempt = false; } @@ -298,7 +298,7 @@ void EditorSpinSlider::_notification(int p_what) { grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5); if (mousewheel_over_grabber) { - InputFilter::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size); + Input::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size); } grabber_range = width; @@ -317,7 +317,7 @@ void EditorSpinSlider::_notification(int p_what) { update(); } if (p_what == NOTIFICATION_FOCUS_ENTER) { - if ((InputFilter::get_singleton()->is_action_pressed("ui_focus_next") || InputFilter::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) { + if ((Input::get_singleton()->is_action_pressed("ui_focus_next") || Input::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) { _focus_entered(); } value_input_just_closed = false; diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 7cb18432a7..f0ee5d451f 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -30,7 +30,7 @@ #include "export_template_manager.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/json.h" #include "core/io/zip_io.h" #include "core/os/dir_access.h" @@ -446,7 +446,7 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int void ExportTemplateManager::_begin_template_download(const String &p_url) { - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { OS::get_singleton()->shell_open(p_url); return; } diff --git a/editor/icons/Decal.svg b/editor/icons/Decal.svg new file mode 100644 index 0000000000..fc7bfb8e2c --- /dev/null +++ b/editor/icons/Decal.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc9c9c"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc9c9c" fill-opacity=".392157"/></svg>
\ No newline at end of file diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 6ad2aa4142..45e376a2aa 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1075,24 +1075,15 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { array[Mesh::ARRAY_INDEX] = indices; } - bool generated_tangents = false; - Variant erased_indices; + bool generate_tangents = (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL")); - if (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL")) { + if (generate_tangents) { //must generate mikktspace tangents.. ergh.. Ref<SurfaceTool> st; st.instance(); st->create_from_triangle_arrays(array); - if (!p.has("targets")) { - //morph targets should not be reindexed, as array size might differ - //removing indices is the best bet here - st->deindex(); - erased_indices = a[Mesh::ARRAY_INDEX]; - a[Mesh::ARRAY_INDEX] = Variant(); - } st->generate_tangents(); array = st->commit_to_arrays(); - generated_tangents = true; } Array morphs; @@ -1207,10 +1198,9 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { array_copy[Mesh::ARRAY_TANGENT] = tangents_v4; } - if (generated_tangents) { + if (generate_tangents) { Ref<SurfaceTool> st; st.instance(); - array_copy[Mesh::ARRAY_INDEX] = erased_indices; //needed for tangent generation, erased by deindex st->create_from_triangle_arrays(array_copy); st->deindex(); st->generate_tangents(); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index b5766a48a0..239fae2268 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1429,29 +1429,110 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p Map<Ref<ArrayMesh>, Transform> meshes; _find_meshes(scene, meshes); - if (light_bake_mode == 2) { + String file_id = src_path.get_file(); + String cache_file_path = base_path.plus_file(file_id + ".unwrap_cache"); - float texel_size = p_options["meshes/lightmap_texel_size"]; - texel_size = MAX(0.001, texel_size); + Vector<unsigned char> cache_data; - EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size()); - int step = 0; - for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) { + if (FileAccess::exists(cache_file_path)) { + Error err2; + FileAccess *file = FileAccess::open(cache_file_path, FileAccess::READ, &err2); - Ref<ArrayMesh> mesh = E->key(); - String name = mesh->get_name(); - if (name == "") { //should not happen but.. - name = "Mesh " + itos(step); + if (err2) { + if (file) + memdelete(file); + } else { + int cache_size = file->get_len(); + cache_data.resize(cache_size); + file->get_buffer(cache_data.ptrw(), cache_size); + } + } + + float texel_size = p_options["meshes/lightmap_texel_size"]; + texel_size = MAX(0.001, texel_size); + + Map<String, unsigned int> used_unwraps; + + EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size()); + int step = 0; + for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) { + + Ref<ArrayMesh> mesh = E->key(); + String name = mesh->get_name(); + if (name == "") { //should not happen but.. + name = "Mesh " + itos(step); + } + + progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step); + + int *ret_cache_data = (int *)cache_data.ptrw(); + unsigned int ret_cache_size = cache_data.size(); + bool ret_used_cache = true; // Tell the unwrapper to use the cache + Error err2 = mesh->lightmap_unwrap_cached(ret_cache_data, ret_cache_size, ret_used_cache, E->get(), texel_size); + + if (err2 != OK) { + EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry."); + } else { + + String hash = String::md5((unsigned char *)ret_cache_data); + used_unwraps.insert(hash, ret_cache_size); + + if (!ret_used_cache) { + // Cache was not used, add the generated entry to the current cache + if (cache_data.empty()) { + cache_data.resize(4 + ret_cache_size); + int *data = (int *)cache_data.ptrw(); + data[0] = 1; + memcpy(&data[1], ret_cache_data, ret_cache_size); + } else { + int current_size = cache_data.size(); + cache_data.resize(cache_data.size() + ret_cache_size); + unsigned char *ptrw = cache_data.ptrw(); + memcpy(&ptrw[current_size], ret_cache_data, ret_cache_size); + int *data = (int *)ptrw; + data[0] += 1; + } } + } + step++; + } - progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step); + Error err2; + FileAccess *file = FileAccess::open(cache_file_path, FileAccess::WRITE, &err2); - Error err2 = mesh->lightmap_unwrap(E->get(), texel_size); - if (err2 != OK) { - EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry."); + if (err2) { + if (file) + memdelete(file); + } else { + + // Store number of entries + file->store_32(used_unwraps.size()); + + // Store cache entries + const int *cache = (int *)cache_data.ptr(); + unsigned int r_idx = 1; + for (int i = 0; i < cache[0]; ++i) { + unsigned char *entry_start = (unsigned char *)&cache[r_idx]; + String entry_hash = String::md5(entry_start); + if (used_unwraps.has(entry_hash)) { + unsigned int entry_size = used_unwraps[entry_hash]; + file->store_buffer(entry_start, entry_size); } - step++; + + r_idx += 4; // hash + r_idx += 2; // size hint + + int vertex_count = cache[r_idx]; + r_idx += 1; // vertex count + r_idx += vertex_count; // vertex + r_idx += vertex_count * 2; // uvs + + int index_count = cache[r_idx]; + r_idx += 1; // index count + r_idx += index_count; // indices } + + file->close(); } } diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp new file mode 100644 index 0000000000..a2f178de12 --- /dev/null +++ b/editor/import/resource_importer_shader_file.cpp @@ -0,0 +1,90 @@ +#include "resource_importer_shader_file.h" + +#include "core/io/marshalls.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "editor/editor_node.h" +#include "editor/plugins/shader_file_editor_plugin.h" +#include "servers/rendering/rendering_device_binds.h" + +String ResourceImporterShaderFile::get_importer_name() const { + + return "glsl"; +} + +String ResourceImporterShaderFile::get_visible_name() const { + + return "GLSL Shader File"; +} +void ResourceImporterShaderFile::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("glsl"); +} +String ResourceImporterShaderFile::get_save_extension() const { + return "res"; +} + +String ResourceImporterShaderFile::get_resource_type() const { + + return "RDShaderFile"; +} + +int ResourceImporterShaderFile::get_preset_count() const { + return 0; +} +String ResourceImporterShaderFile::get_preset_name(int p_idx) const { + + return String(); +} + +void ResourceImporterShaderFile::get_import_options(List<ImportOption> *r_options, int p_preset) const { +} + +bool ResourceImporterShaderFile::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + return true; +} +static String _include_function(const String &p_path, void *userpointer) { + Error err; + + String *base_path = (String *)userpointer; + + String include = p_path; + if (include.is_rel_path()) { + include = base_path->plus_file(include); + } + + FileAccessRef file_inc = FileAccess::open(include, FileAccess::READ, &err); + if (err != OK) { + return String(); + } + return file_inc->get_as_utf8_string(); +} + +Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + + /* STEP 1, Read shader code */ + + Error err; + FileAccessRef file = FileAccess::open(p_source_file, FileAccess::READ, &err); + ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN); + ERR_FAIL_COND_V(!file.operator->(), ERR_CANT_OPEN); + + String file_txt = file->get_as_utf8_string(); + Ref<RDShaderFile> shader_file; + shader_file.instance(); + String base_path = p_source_file.get_base_dir(); + err = shader_file->parse_versions_from_text(file_txt, _include_function, &base_path); + + if (err != OK) { + if (!ShaderFileEditor::singleton->is_visible_in_tree()) { + EditorNode::get_singleton()->add_io_error(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file)); + } + } + + ResourceSaver::save(p_save_path + ".res", shader_file); + + return OK; +} + +ResourceImporterShaderFile::ResourceImporterShaderFile() { +} diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h new file mode 100644 index 0000000000..f6b50bee9e --- /dev/null +++ b/editor/import/resource_importer_shader_file.h @@ -0,0 +1,27 @@ +#ifndef RESOURCE_IMPORTER_SHADER_FILE_H +#define RESOURCE_IMPORTER_SHADER_FILE_H + +#include "core/io/resource_importer.h" + +class ResourceImporterShaderFile : public ResourceImporter { + GDCLASS(ResourceImporterShaderFile, ResourceImporter); + +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr); + + ResourceImporterShaderFile(); +}; + +#endif // RESOURCE_IMPORTER_SHADER_FILE_H diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 724782ac44..31a8320209 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -4219,6 +4219,21 @@ Joint3DGizmoPlugin::Joint3DGizmoPlugin() { create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1))); create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1))); create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1))); + + update_timer = memnew(Timer); + update_timer->set_name("JointGizmoUpdateTimer"); + update_timer->set_wait_time(1.0 / 120.0); + update_timer->connect("timeout", callable_mp(this, &Joint3DGizmoPlugin::incremental_update_gizmos)); + update_timer->set_autostart(true); + EditorNode::get_singleton()->call_deferred("add_child", update_timer); +} + +void Joint3DGizmoPlugin::incremental_update_gizmos() { + if (!current_gizmos.empty()) { + update_idx++; + update_idx = update_idx % current_gizmos.size(); + redraw(current_gizmos[update_idx]); + } } bool Joint3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index 8bc52b6ba9..6432feeecb 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -409,6 +409,11 @@ class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(Joint3DGizmoPlugin, EditorNode3DGizmoPlugin); + Timer *update_timer; + uint64_t update_idx = 0; + + void incremental_update_gizmos(); + public: bool has_gizmo(Node3D *p_spatial); String get_name() const; diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp index 4343535eb6..17cb68df3a 100644 --- a/editor/plugins/animation_blend_space_2d_editor.cpp +++ b/editor/plugins/animation_blend_space_2d_editor.cpp @@ -30,7 +30,7 @@ #include "animation_blend_space_2d_editor.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/delaunay.h" #include "core/os/keyboard.h" diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 54c60aba71..23e547f55d 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "animation_blend_tree_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/os/keyboard.h" #include "core/project_settings.h" diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index d96a3b0bab..db51c5c6ba 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "animation_player_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" @@ -488,7 +488,7 @@ double AnimationPlayerEditor::_get_editor_step() const { ERR_FAIL_COND_V(!anim.is_valid(), 0.0); // Use more precise snapping when holding Shift - return InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step(); + return Input::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step(); } return 0.0; diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index c06f62a8c1..c28f533958 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -30,7 +30,7 @@ #include "animation_state_machine_editor.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/delaunay.h" #include "core/os/keyboard.h" diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index e771c5610f..9452c0f11b 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -34,7 +34,7 @@ #include "animation_blend_space_2d_editor.h" #include "animation_blend_tree_editor_plugin.h" #include "animation_state_machine_editor.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/delaunay.h" #include "core/os/keyboard.h" diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 14c44b7973..bb5147972c 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "asset_library_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/json.h" #include "core/os/keyboard.h" #include "core/version.h" diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index cd3df08276..79111762b2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "canvas_item_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/print_string.h" #include "core/project_settings.h" @@ -334,7 +334,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; - bool is_snap_active = smart_snap_active ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // Smart snap using the canvas position Vector2 output = p_target; @@ -462,7 +462,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig } float CanvasItemEditor::snap_angle(float p_target, float p_start) const { - if (((smart_snap_active || snap_rotation) ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) { + if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) { if (snap_relative) { return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step); } else { @@ -1284,7 +1284,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo // Pan the viewport Point2i relative; if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { - relative = InputFilter::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect()); + relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect()); } else { relative = m->get_relative(); } @@ -1912,7 +1912,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; bool uniform = m->get_shift(); - bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); Point2 drag_from_local = simple_xform.xform(drag_from); Point2 drag_to_local = simple_xform.xform(drag_to); @@ -2214,10 +2214,10 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (k.is_valid() && !k->is_pressed() && drag_type == DRAG_KEY_MOVE && tool == TOOL_SELECT && (k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_LEFT || k->get_keycode() == KEY_RIGHT)) { // Confirm canvas items move by arrow keys - if ((!InputFilter::get_singleton()->is_key_pressed(KEY_UP)) && - (!InputFilter::get_singleton()->is_key_pressed(KEY_DOWN)) && - (!InputFilter::get_singleton()->is_key_pressed(KEY_LEFT)) && - (!InputFilter::get_singleton()->is_key_pressed(KEY_RIGHT))) { + if ((!Input::get_singleton()->is_key_pressed(KEY_UP)) && + (!Input::get_singleton()->is_key_pressed(KEY_DOWN)) && + (!Input::get_singleton()->is_key_pressed(KEY_LEFT)) && + (!Input::get_singleton()->is_key_pressed(KEY_RIGHT))) { _commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true); drag_type = DRAG_NONE; } @@ -3310,8 +3310,8 @@ void CanvasItemEditor::_draw_selection() { } // Draw the move handles - bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); - bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT); + bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); if (tool == TOOL_MOVE && show_transformation_gizmos) { if (_is_node_movable(canvas_item)) { Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized(); @@ -3347,7 +3347,7 @@ void CanvasItemEditor::_draw_selection() { Transform2D simple_xform = viewport->get_transform() * unscaled_transform; Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); - bool uniform = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); + bool uniform = Input::get_singleton()->is_key_pressed(KEY_SHIFT); Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom; if (drag_type == DRAG_SCALE_X) { @@ -6204,8 +6204,8 @@ bool CanvasItemEditorViewport::_only_packed_scenes_selected() const { } void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) { - bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); - bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT); + bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); + bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); selected_files.clear(); Dictionary d = p_data; diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index 26adc5156b..1cee1a040f 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -31,7 +31,7 @@ #include "collision_polygon_3d_editor_plugin.h" #include "canvas_item_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "editor/editor_settings.h" @@ -342,7 +342,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con Vector2 cpoint(spoint.x, spoint.y); - if (snap_ignore && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { snap_ignore = false; } diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 71c5a78e0b..9b5c6bae3b 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -32,7 +32,7 @@ #include "canvas_item_editor_plugin.h" #include "core/core_string_names.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" @@ -210,7 +210,7 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { else tangent = 9999 * (dir.y >= 0 ? 1 : -1); - bool link = !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); + bool link = !Input::get_singleton()->is_key_pressed(KEY_SHIFT); if (_selected_tangent == TANGENT_LEFT) { curve.set_point_left_tangent(_selected_point, tangent); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 354c951a7c..af34dd5cab 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "node_3d_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/camera_matrix.h" #include "core/os/keyboard.h" #include "core/print_string.h" @@ -298,10 +298,10 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia"); //determine if being manipulated - bool manipulated = InputFilter::get_singleton()->get_mouse_button_mask() & (2 | 4); - manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); - manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_ALT); - manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL); float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia); float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia); @@ -2260,7 +2260,7 @@ void Node3DEditorViewport::scale_freelook_speed(real_t scale) { Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { Point2i relative; if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) { - relative = InputFilter::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); + relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); } else { relative = p_ev_mouse_motion->get_relative(); } @@ -2276,7 +2276,7 @@ static bool is_shortcut_pressed(const String &p_path) { if (k == nullptr) { return false; } - const InputFilter &input = *InputFilter::get_singleton(); + const Input &input = *Input::get_singleton(); int keycode = k->get_keycode(); return input.is_key_pressed(keycode); } @@ -2287,9 +2287,27 @@ void Node3DEditorViewport::_update_freelook(real_t delta) { return; } - const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int(); + + Vector3 forward; + if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Forward/backward keys will always go straight forward/backward, never moving on the Y axis. + forward = Vector3(0, 0, -1).rotated(Vector3(0, 1, 0), camera->get_rotation().y); + } else { + // Forward/backward keys will be relative to the camera pitch. + forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + } + const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); - const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + + Vector3 up; + if (navigation_scheme == FREELOOK_PARTIALLY_AXIS_LOCKED || navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Up/down keys will always go up/down regardless of camera pitch. + up = Vector3(0, 1, 0); + } else { + // Up/down keys will be relative to the camera pitch. + up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + } Vector3 direction; @@ -3810,7 +3828,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ if (!can_drop_data_fw(p_point, p_data, p_from)) return; - bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); + bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); selected_files.clear(); Dictionary d = p_data; @@ -5767,7 +5785,7 @@ void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) { if (!is_visible_in_tree()) return; - snap_key_enabled = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL); } void Node3DEditor::_notification(int p_what) { @@ -6428,7 +6446,7 @@ Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const { float Node3DEditor::get_translate_snap() const { float snap_value; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { snap_value = snap_translate->get_text().to_double() / 10.0; } else { snap_value = snap_translate->get_text().to_double(); @@ -6439,7 +6457,7 @@ float Node3DEditor::get_translate_snap() const { float Node3DEditor::get_rotate_snap() const { float snap_value; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { snap_value = snap_rotate->get_text().to_double() / 3.0; } else { snap_value = snap_rotate->get_text().to_double(); @@ -6450,7 +6468,7 @@ float Node3DEditor::get_rotate_snap() const { float Node3DEditor::get_scale_snap() const { float snap_value; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { snap_value = snap_scale->get_text().to_double() / 2.0; } else { snap_value = snap_scale->get_text().to_double(); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 2c3b15cfc8..71da14ae1a 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -241,6 +241,12 @@ public: NAVIGATION_MODO, }; + enum FreelookNavigationScheme { + FREELOOK_DEFAULT, + FREELOOK_PARTIALLY_AXIS_LOCKED, + FREELOOK_FULLY_AXIS_LOCKED, + }; + private: float cpu_time_history[FRAME_TIME_HISTORY]; int cpu_time_history_index; @@ -850,12 +856,11 @@ public: static const int HIDDEN = 1; static const int ON_TOP = 2; -private: +protected: int current_state; List<EditorNode3DGizmo *> current_gizmos; HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; -protected: static void _bind_methods(); virtual bool has_gizmo(Node3D *p_spatial); virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 1f7a5b9968..e15d8556e4 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -31,7 +31,7 @@ #include "polygon_2d_editor_plugin.h" #include "canvas_item_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" @@ -810,7 +810,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { if (mm.is_valid()) { - if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) { + if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 drag(mm->get_relative().x, mm->get_relative().y); uv_hscroll->set_value(uv_hscroll->get_value() - drag.x); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 2c831979de..80d97e7fa9 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "script_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" @@ -1545,7 +1545,7 @@ void ScriptEditor::_help_overview_selected(int p_idx) { void ScriptEditor::_script_selected(int p_idx) { - grab_focus_block = !InputFilter::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing + grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing _go_to_tab(script_list->get_item_metadata(p_idx)); grab_focus_block = false; @@ -1866,6 +1866,10 @@ void ScriptEditor::_update_script_names() { if (new_cur_tab == -1 && sedata[i].index == cur_tab) { new_cur_tab = i; } + // Update index of sd entries for sorted order + _ScriptEditorItemData sd = sedata[i]; + sd.index = i; + sedata.set(i, sd); } tab_container->set_current_tab(new_prev_tab); tab_container->set_current_tab(new_cur_tab); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 4b8383e1e5..1a77eeb9de 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -172,7 +172,7 @@ void ScriptTextEditor::_update_member_keywords() { for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { String name = E->get().name; - if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP) + if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) continue; if (name.find("/") != -1) continue; diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp new file mode 100644 index 0000000000..296c7a01b6 --- /dev/null +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -0,0 +1,303 @@ +#include "shader_file_editor_plugin.h" + +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" +#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" + +/*** SHADER SCRIPT EDITOR ****/ + +/*** SCRIPT EDITOR ******/ + +void ShaderFileEditor::_update_version(const StringName &p_version_txt, const RD::ShaderStage p_stage) { +} + +void ShaderFileEditor::_version_selected(int p_option) { + + int c = versions->get_current(); + StringName version_txt = versions->get_item_metadata(c); + + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + int first_found = -1; + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_txt); + ERR_FAIL_COND(bytecode.is_null()); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) { + stages[i]->set_icon(Ref<Texture2D>()); + continue; + } + + Ref<Texture2D> icon; + if (bytecode->get_stage_compile_error(RD::ShaderStage(i)) != String()) { + icon = get_theme_icon("ImportFail", "EditorIcons"); + } else { + icon = get_theme_icon("ImportCheck", "EditorIcons"); + } + stages[i]->set_icon(icon); + + if (first_found == -1) { + first_found = i; + } + + if (stages[i]->is_pressed()) { + stage = RD::ShaderStage(i); + break; + } + } + + error_text->clear(); + + if (stage == RD::SHADER_STAGE_MAX) { //need to change stage, does not have it + if (first_found == -1) { + error_text->add_text(TTR("No valid shader stages found.")); + return; //well you did not put any stage I guess? + } + stages[first_found]->set_pressed(true); + stage = RD::ShaderStage(first_found); + } + + String error = bytecode->get_stage_compile_error(stage); + + error_text->push_font(get_theme_font("source", "EditorFonts")); + + if (error == String()) { + error_text->add_text(TTR("Shader stage compiled without errors.")); + } else { + error_text->add_text(error); + } +} + +void ShaderFileEditor::_update_options() { + + ERR_FAIL_COND(shader_file.is_null()); + + if (shader_file->get_base_error() != String()) { + stage_hb->hide(); + versions->hide(); + error_text->clear(); + error_text->push_font(get_theme_font("source", "EditorFonts")); + error_text->add_text(vformat(TTR("File structure for '%s' contains unrecoverable errors:\n\n"), shader_file->get_path().get_file())); + error_text->add_text(shader_file->get_base_error()); + return; + } + + stage_hb->show(); + versions->show(); + + int c = versions->get_current(); + //remember current + versions->clear(); + Vector<StringName> version_list = shader_file->get_version_list(); + + if (c >= version_list.size()) { + c = version_list.size() - 1; + } + if (c < 0) { + c = 0; + } + + StringName current_version; + + for (int i = 0; i < version_list.size(); i++) { + String title = version_list[i]; + if (title == "") { + title = "default"; + } + + Ref<Texture2D> icon; + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_list[i]); + ERR_FAIL_COND(bytecode.is_null()); + + bool failed = false; + for (int j = 0; j < RD::SHADER_STAGE_MAX; j++) { + String error = bytecode->get_stage_compile_error(RD::ShaderStage(j)); + if (error != String()) { + failed = true; + } + } + + if (failed) { + icon = get_theme_icon("ImportFail", "EditorIcons"); + } else { + icon = get_theme_icon("ImportCheck", "EditorIcons"); + } + + versions->add_item(title, icon); + versions->set_item_metadata(i, version_list[i]); + + if (i == c) { + versions->select(i); + current_version = version_list[i]; + } + } + + if (version_list.size() == 0) { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + stages[i]->set_disabled(true); + } + return; + } + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(current_version); + ERR_FAIL_COND(bytecode.is_null()); + int first_valid = -1; + int current = -1; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i)); + String error = bytecode->get_stage_compile_error(RD::ShaderStage(i)); + bool disable = error == String() && bc.empty(); + stages[i]->set_disabled(disable); + if (!disable) { + if (stages[i]->is_pressed()) { + current = i; + } + first_valid = i; + } + } + + if (current == -1 && first_valid != -1) { + stages[first_valid]->set_pressed(true); + } + + _version_selected(0); +} + +void ShaderFileEditor::_notification(int p_what) { + + if (p_what == NOTIFICATION_WM_FOCUS_IN) { + if (is_visible_in_tree() && shader_file.is_valid()) { + _update_options(); + } + } +} + +void ShaderFileEditor::_editor_settings_changed() { + + if (is_visible_in_tree() && shader_file.is_valid()) { + _update_options(); + } +} + +void ShaderFileEditor::_bind_methods() { +} + +void ShaderFileEditor::edit(const Ref<RDShaderFile> &p_shader) { + + if (p_shader.is_null()) { + if (shader_file.is_valid()) { + shader_file->disconnect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed)); + } + return; + } + + if (shader_file == p_shader) + return; + + shader_file = p_shader; + + if (shader_file.is_valid()) { + shader_file->connect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed)); + } + + _update_options(); +} + +void ShaderFileEditor::_shader_changed() { + + if (is_visible_in_tree()) { + _update_options(); + } +} + +ShaderFileEditor *ShaderFileEditor::singleton = nullptr; + +ShaderFileEditor::ShaderFileEditor(EditorNode *p_node) { + singleton = this; + HSplitContainer *main_hs = memnew(HSplitContainer); + + add_child(main_hs); + + versions = memnew(ItemList); + versions->connect("item_selected", callable_mp(this, &ShaderFileEditor::_version_selected)); + versions->set_custom_minimum_size(Size2i(200 * EDSCALE, 0)); + main_hs->add_child(versions); + + VBoxContainer *main_vb = memnew(VBoxContainer); + main_vb->set_h_size_flags(SIZE_EXPAND_FILL); + main_hs->add_child(main_vb); + + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "Vertex", + "Fragment", + "TessControl", + "TessEval", + "Compute" + }; + + stage_hb = memnew(HBoxContainer); + main_vb->add_child(stage_hb); + + Ref<ButtonGroup> bg; + bg.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + Button *button = memnew(Button(stage_str[i])); + button->set_toggle_mode(true); + button->set_focus_mode(FOCUS_NONE); + stage_hb->add_child(button); + stages[i] = button; + button->set_button_group(bg); + button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected), varray(i)); + } + + error_text = memnew(RichTextLabel); + error_text->set_v_size_flags(SIZE_EXPAND_FILL); + main_vb->add_child(error_text); +} + +void ShaderFileEditorPlugin::edit(Object *p_object) { + + RDShaderFile *s = Object::cast_to<RDShaderFile>(p_object); + shader_editor->edit(s); +} + +bool ShaderFileEditorPlugin::handles(Object *p_object) const { + + RDShaderFile *shader = Object::cast_to<RDShaderFile>(p_object); + return shader != nullptr; +} + +void ShaderFileEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + editor->make_bottom_panel_item_visible(shader_editor); + + } else { + + button->hide(); + if (shader_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + } +} + +ShaderFileEditorPlugin::ShaderFileEditorPlugin(EditorNode *p_node) { + + editor = p_node; + shader_editor = memnew(ShaderFileEditor(p_node)); + + shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); + button = editor->add_bottom_panel_item(TTR("ShaderFile"), shader_editor); + button->hide(); +} + +ShaderFileEditorPlugin::~ShaderFileEditorPlugin() { +} diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h new file mode 100644 index 0000000000..44d32de2f1 --- /dev/null +++ b/editor/plugins/shader_file_editor_plugin.h @@ -0,0 +1,64 @@ +#ifndef SHADER_FILE_EDITOR_PLUGIN_H +#define SHADER_FILE_EDITOR_PLUGIN_H + +#include "editor/code_editor.h" +#include "editor/editor_plugin.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/text_edit.h" +#include "scene/main/timer.h" +#include "servers/rendering/rendering_device_binds.h" + +class ShaderFileEditor : public PanelContainer { + + GDCLASS(ShaderFileEditor, PanelContainer); + + Ref<RDShaderFile> shader_file; + + HBoxContainer *stage_hb; + ItemList *versions; + Button *stages[RD::SHADER_STAGE_MAX]; + RichTextLabel *error_text; + + void _update_version(const StringName &p_version_txt, const RenderingDevice::ShaderStage p_stage); + void _version_selected(int p_stage); + void _editor_settings_changed(); + + void _update_options(); + void _shader_changed(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static ShaderFileEditor *singleton; + void edit(const Ref<RDShaderFile> &p_shader); + + ShaderFileEditor(EditorNode *p_node); +}; + +class ShaderFileEditorPlugin : public EditorPlugin { + + GDCLASS(ShaderFileEditorPlugin, EditorPlugin); + + ShaderFileEditor *shader_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "ShaderFile"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + + ShaderFileEditor *get_shader_editor() const { return shader_editor; } + + ShaderFileEditorPlugin(EditorNode *p_node); + ~ShaderFileEditorPlugin(); +}; + +#endif // SHADER_FILE_EDITOR_PLUGIN_H diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 8892d13f51..099c9ceb5d 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -31,7 +31,7 @@ #include "texture_region_editor_plugin.h" #include "core/core_string_names.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "scene/gui/check_box.h" @@ -307,7 +307,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { if (E->get().has_point(point)) { rect = E->get(); - if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL) && !(InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) { + if (Input::get_singleton()->is_key_pressed(KEY_CONTROL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) { Rect2 r; if (node_sprite) r = node_sprite->get_region_rect(); @@ -449,7 +449,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { if (mm.is_valid()) { - if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) { + if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom); hscroll->set_value(hscroll->get_value() - dragged.x); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index ce421ac0a5..e22e0cc052 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -31,7 +31,7 @@ #include "tile_map_editor_plugin.h" #include "canvas_item_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/math_funcs.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" @@ -57,17 +57,18 @@ void TileMapEditor::_notification(int p_what) { } break; + case NOTIFICATION_ENTER_TREE: { + + get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed)); + [[fallthrough]]; + } + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { if (is_visible_in_tree()) { _update_palette(); } - [[fallthrough]]; - } - case NOTIFICATION_ENTER_TREE: { - - get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed)); paint_button->set_icon(get_theme_icon("Edit", "EditorIcons")); bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons")); picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons")); @@ -996,7 +997,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (mb->is_pressed()) { - if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) + if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return false; // Drag. if (tool == TOOL_NONE) { @@ -1377,7 +1378,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } - if (tool == TOOL_PICKING && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { _pick_tile(over_tile); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index d1dda68c1d..c393b15a97 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "tile_set_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "editor/editor_scale.h" #include "editor/plugins/canvas_item_editor_plugin.h" @@ -1113,7 +1113,7 @@ void TileSetEditor::_on_workspace_draw() { void TileSetEditor::_on_workspace_process() { - if (InputFilter::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) { + if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) { if (!tile_names_visible) { tile_names_visible = true; workspace_overlay->update(); @@ -1395,7 +1395,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) { dragging = true; erasing = (mb->get_button_index() == BUTTON_RIGHT); - alternative = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT); + alternative = Input::get_singleton()->is_key_pressed(KEY_SHIFT); Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y))); Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y)); pos = mb->get_position() - (pos + current_tile_region.position); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index d5128db0d5..a7e737fdd2 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -30,7 +30,7 @@ #include "visual_shader_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "core/os/keyboard.h" @@ -1635,7 +1635,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty()); popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty()); menu_point = graph->get_local_mouse_position(); - Point2 gpos = InputFilter::get_singleton()->get_mouse_position(); + Point2 gpos = Input::get_singleton()->get_mouse_position(); popup_menu->set_position(gpos); popup_menu->popup(); } @@ -1648,7 +1648,7 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) { saved_node_pos_dirty = true; saved_node_pos = graph->get_local_mouse_position(); - Point2 gpos = InputFilter::get_singleton()->get_mouse_position(); + Point2 gpos = Input::get_singleton()->get_mouse_position(); members_dialog->popup(); members_dialog->set_position(gpos); } else { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 0ca540a33f..c918a799e1 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -2779,6 +2779,8 @@ void ProjectListFilter::add_filter_option() { void ProjectListFilter::add_search_box() { search_box = memnew(LineEdit); search_box->set_placeholder(TTR("Search")); + search_box->set_tooltip( + TTR("The search box filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character.")); search_box->connect("text_changed", callable_mp(this, &ProjectListFilter::_search_text_changed)); search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); add_child(search_box); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 978c95b9c8..60329fb7bc 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -31,7 +31,7 @@ #include "property_editor.h" #include "core/class_db.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" @@ -1720,7 +1720,7 @@ real_t CustomPropertyEditor::_parse_real_expression(String text) { void CustomPropertyEditor::_emit_changed_whole_or_field() { - if (!InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { emit_signal("variant_changed"); } else { emit_signal("variant_field_changed", field_names[focused_value_editor]); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index a729f62123..92f899a35d 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -30,7 +30,7 @@ #include "scene_tree_dock.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/resource_saver.h" #include "core/os/keyboard.h" #include "core/project_settings.h" @@ -1030,7 +1030,7 @@ void SceneTreeDock::_node_collapsed(Object *p_obj) { if (!ti) return; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { _set_collapsed_recursive(ti, ti->is_collapsed()); } } @@ -2346,7 +2346,7 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) { int to_pos = -1; _normalize_drop(to_node, to_pos, p_type); - _do_reparent(to_node, to_pos, nodes, !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)); + _do_reparent(to_node, to_pos, nodes, !Input::get_singleton()->is_key_pressed(KEY_SHIFT)); } void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) { @@ -2867,6 +2867,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel edit_local->set_h_size_flags(SIZE_EXPAND_FILL); edit_local->set_text(TTR("Local")); edit_local->set_toggle_mode(true); + edit_local->set_pressed(true); edit_local->connect("pressed", callable_mp(this, &SceneTreeDock::_local_tree_selected)); remote_tree = nullptr; diff --git a/editor/translations/af.po b/editor/translations/af.po index d9e1753c65..fb354fa199 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -9944,6 +9944,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11063,6 +11070,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 2ea1bd1dd5..6181580a68 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -39,7 +39,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-15 14:29+0000\n" +"PO-Revision-Date: 2020-04-27 08:24+0000\n" "Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" @@ -49,7 +49,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -448,7 +448,7 @@ msgstr "لا يمكن إضاÙØ© مقطع جديد بدون جذر" #: editor/animation_track_editor.cpp msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "" +msgstr "مقطع غير متواÙÙ‚ مع منØنى بيزير Bezier (خصائص Ùرعية غير متواÙقة)" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" @@ -710,9 +710,8 @@ msgid "Line Number:" msgstr "رقم الخط:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "تم إستبدال %d" +msgstr "تم إستبدال %d." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." @@ -829,9 +828,8 @@ msgid "Extra Call Arguments:" msgstr "وسائط إستدعاء إضاÙية :" #: editor/connections_dialog.cpp -#, fuzzy msgid "Receiver Method:" -msgstr "إختر طريقة" +msgstr "الدالة المÙتلقنة:" #: editor/connections_dialog.cpp msgid "Advanced" @@ -878,7 +876,6 @@ msgid "Connect" msgstr "وصل" #: editor/connections_dialog.cpp -#, fuzzy msgid "Signal:" msgstr "إشارة:" @@ -1214,9 +1211,8 @@ msgid "Error opening package file, not in ZIP format." msgstr "Øدث خطأ عندÙØªØ Ù…Ù„Ù Ø§Ù„Øزمة بسبب أن المل٠ليس ÙÙŠ صيغة \"ZIP\"." #: editor/editor_asset_installer.cpp -#, fuzzy msgid "%s (Already Exists)" -msgstr "التØميل التلقائي '%s' موجود اصلا!" +msgstr "%s (موجود أصلاً!)" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" @@ -1228,7 +1224,7 @@ msgstr "Ùشل استخراج الملÙات التالية من الØزمة:" #: editor/editor_asset_installer.cpp msgid "And %s more files." -msgstr "%s مزيد من الملÙات" +msgstr "Ùˆ %s أيضاً من الملÙات." #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" @@ -1240,9 +1236,8 @@ msgid "Success!" msgstr "تم بشكل ناجØ!" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Package Contents:" -msgstr "المØتويات:" +msgstr "Ù…Øتويات الرزمة:" #: editor/editor_asset_installer.cpp editor/editor_node.cpp msgid "Install" @@ -1436,18 +1431,16 @@ msgid "Must not collide with an existing engine class name." msgstr "إسم غير صالØØŒ يجب أن لا يتصادم مع أسم Ùئة خاصة بالمØرك." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing built-in type name." -msgstr "إسم غير صالØØŒ يجب أن لا يتصادم مع الأسماء المبنية تلقائياً الموجودة." +msgstr "اسم غير ØµØ§Ù„Ø ÙŠØ¬Ø¨ ألا يتضارب مع اسم موجود ومبني ضمناً بالمØرك." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "إسم غير صالØØŒ ييجب ألاّ يتصادم مع إسم موجود لثابت عمومي." +msgstr "اإسم غير صالØØŒ ييجب ألاّ يتضارب مع اسم ثابت عام موجود سلÙاً." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "لا يمكن استخدام الكلمة المÙتاØية كاسم التØميل التلقائي." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1478,7 +1471,6 @@ msgid "Rearrange Autoloads" msgstr "اعادة ترتيب التØميلات التلقائية" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "مسار غير صالØ." @@ -1540,9 +1532,8 @@ msgid "[unsaved]" msgstr "[غير Ù…ØÙوظ]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "من Ùضلك Øدد الوجهة الأساسية أولاً" +msgstr "من Ùضلك Øدد الوجهة الأساسية أولاً." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1605,6 +1596,10 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" +"تتطلب المنصة المستهدÙØ© ضغط الرسومات النقشية 'ETC' texture ليرجع المعرّ٠إلى " +"GLES2.\n" +"مكّن 'استيراد Etc' ÙÙŠ إعدادات المشروع، أو عطّل 'تمكين التواÙÙ‚ الرجعي للتعريÙات " +"Driver Fallback Enabled'." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1624,20 +1619,19 @@ msgstr "مل٠النموذج غير موجود:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "لا يمكن لمÙصدرات 32-bit التي تتضمن PCK أن تكون أكبر من 4 GiB." #: editor/editor_feature_profile.cpp msgid "3D Editor" -msgstr "معدل تلاثي الأبعاد" +msgstr "Ù…Øرر تلاثي الأبعاد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "ÙØªØ Ù…Ùعدل الكود" +msgstr "Ù…Øرر النص البرمجي" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "مكتبة الأصول" +msgstr "مكتبة المÙÙ„Øقات" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -1649,87 +1643,77 @@ msgstr "رصي٠الاستيراد" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "رصي٠العقد" +msgstr "رصي٠العÙقد" #: editor/editor_feature_profile.cpp msgid "FileSystem and Import Docks" msgstr "رصي٠نظام الملÙات Ùˆ الاستيراد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "إستبدال الكل" +msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ù„Ù Ø§Ù„Ø´Ø®ØµÙŠ '%s'ØŸ (لا تراجع)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "ينبغي أن يكون المل٠الشخصي اسم Ù…Ù„Ù ØµØ§Ù„Ø ÙˆØ£Ù„Ù‘Ø§ ÙŠØتوي '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "مل٠أو مجلد مع هذا الأسم موجود بالÙعل." +msgstr "ملÙÙŒ بهذا الاسم موجود بالÙعل." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(المØرر Ù…Ùعطّل، الخاصيات Ù…Ùعطّلة)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "خصائص Ùقط" +msgstr "(الخاصيات Ù…Ùعطّلة)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "معطّل" +msgstr "(المÙØرر Ù…Ùعطّل)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "وص٠الصÙ:" +msgstr "إعدادات الص٠Class:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "ÙØªØ ÙÙŠ المÙعدل التالي" +msgstr "مكّن المØرر السياقي Contextual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "خصائص:" +msgstr "الخصائص المÙمكّنة:" #: editor/editor_feature_profile.cpp msgid "Enabled Features:" -msgstr "الميزات المÙعلة:" +msgstr "الميزات المÙمكّنة:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "إبØØ« ÙÙŠ الأصناÙ" +msgstr "الصÙو٠المÙمكّنة:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "لاØقة المل٠'%s' غير صالØØ©ØŒ أجهض الإستيراد." #: editor/editor_feature_profile.cpp msgid "" "Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "الملÙ'%s' موجود سلÙاً، قم بإزالته بداية قبل الاستيراد، أجهض الإستيراد." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "خطأ ÙÙŠ ØÙظ مجموعة البلاط!" +msgstr "خطأ ÙÙŠ ØÙظ المل٠إلى المسار: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "غير Ù…ÙØدد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Current Profile:" -msgstr "النسخة الØالية:" +msgstr "المل٠(النسخة) الØالية:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1752,44 +1736,36 @@ msgid "Export" msgstr "تصدير" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Available Profiles:" -msgstr "خصائص:" +msgstr "الملÙات المتواÙرة:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "وص٠الصÙ" +msgstr "إعدادات الص٠Class" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "إسم جديد:" +msgstr "اسم Ù…ÙŽÙ„Ù profile جديد:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "زر الÙأرة الأيمن: Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©." +msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ù„Ù" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Godot Feature Profile" -msgstr "إدارة قوالب التصدير" +msgstr "ملÙات غودوت المÙرشّØØ©" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "%d مزيد من الملÙات" +msgstr "استيراد الملÙ(الملÙات)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "تصدير المشروع" +msgstr "تصدير الملÙ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "إدارة قوالب التصدير" +msgstr "تدبير Ù…Øرر الملÙات المÙرشØØ©" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1800,7 +1776,6 @@ msgid "File Exists, Overwrite?" msgstr "المل٠موجود، إستبدال؟" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select This Folder" msgstr "Øدد هذا المجلد" @@ -1809,13 +1784,11 @@ msgid "Copy Path" msgstr "نسخ المسار" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "أظهر ÙÙŠ مدير الملÙات" +msgstr "اÙØªØ ÙÙŠ مدير الملÙات" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp -#, fuzzy msgid "Show in File Manager" msgstr "أظهر ÙÙŠ مدير الملÙات" @@ -1965,7 +1938,7 @@ msgstr "ÙØص المصادر" msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" -msgstr "" +msgstr "هناك عدة مستوردات مخصوصة لعدة أنواع Øددت المل٠%sØŒ أجهض الإستيراد" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -1989,7 +1962,6 @@ msgid "Inherited by:" msgstr "مورث بواسطة:" #: editor/editor_help.cpp -#, fuzzy msgid "Description" msgstr "الوصÙ:" @@ -2004,7 +1976,7 @@ msgstr "خصائص" #: editor/editor_help.cpp msgid "override:" -msgstr "" +msgstr "يتجاوز:" #: editor/editor_help.cpp #, fuzzy @@ -2143,7 +2115,7 @@ msgstr "مجموعة" #: editor/editor_inspector.cpp msgid "Set Multiple:" -msgstr "" +msgstr "تØديد التكرار:" #: editor/editor_log.cpp msgid "Output:" @@ -2180,8 +2152,9 @@ msgid "Start" msgstr "بدء!" #: editor/editor_network_profiler.cpp +#, fuzzy msgid "%s/s" -msgstr "" +msgstr "%s/s" #: editor/editor_network_profiler.cpp #, fuzzy @@ -2198,19 +2171,19 @@ msgstr "عقدة" #: editor/editor_network_profiler.cpp msgid "Incoming RPC" -msgstr "" +msgstr "نداء إجراء بعيد وادر" #: editor/editor_network_profiler.cpp msgid "Incoming RSET" -msgstr "" +msgstr "RSET (ناقل الØالة التمثيلية) وارد" #: editor/editor_network_profiler.cpp msgid "Outgoing RPC" -msgstr "" +msgstr "نداء الإجراء البعيد RPC صادر" #: editor/editor_network_profiler.cpp msgid "Outgoing RSET" -msgstr "" +msgstr "ناقل الØالة التمثيلية RSET صادر" #: editor/editor_node.cpp editor/project_manager.cpp msgid "New Window" @@ -2218,7 +2191,7 @@ msgstr "ناÙذة جديدة" #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "لا يمكن ØÙظ الموارد المستوردة." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -2234,6 +2207,8 @@ msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" +"لا يمكن ØÙظ هذا المورد كونه لا ينتمي إلى المشهد الذي تم تØريره. اجعله مميزاً " +"بداية." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." @@ -2253,7 +2228,7 @@ msgstr "خطأ خلال الØÙظ." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "" +msgstr "لا يمكن ÙØªØ '%s'. ربما تم Øذ٠المل٠أو نقله." #: editor/editor_node.cpp msgid "Error while parsing '%s'." @@ -2285,13 +2260,15 @@ msgstr "ينشئ الصورة المصغرة" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." -msgstr "هذه العملية لا يمكنها الإكتمال من غير جزر الشجرة." +msgstr "هذه العملية لا يمكنها الإكتمال من غير شجرة رئيسة." #: editor/editor_node.cpp msgid "" "This scene can't be saved because there is a cyclic instancing inclusion.\n" "Please resolve it and then attempt to save again." msgstr "" +"لا يمكن ØÙظ هذا المشهد كونخ يتضمن نمذجة دورية cyclic instancing.\n" +"من Ùضلك قم بØÙ„ تلك المشكلة ومن ثمَّ Øاول من جديد." #: editor/editor_node.cpp msgid "" @@ -2301,7 +2278,7 @@ msgstr "لا يمكن ØÙظ المشهد. على Ø§Ù„Ø£Ø±Ø¬Ø Ù„Ø§ يمكن Ø¥Ø #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "لا يمكن الكتابة عنوة (استبدال overwrite ) المشهد كونه ما زال Ù…ÙتوØاً!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" @@ -2434,7 +2411,7 @@ msgstr "Ùشل تØميل المورد." #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "" +msgstr "يتطلب ØÙظ المشهد تواÙر عÙقدة رئيسة." #: editor/editor_node.cpp msgid "Save Scene As..." @@ -2663,7 +2640,7 @@ msgstr "أغلق الألسنة الاخرى" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "أغلق التبويبات على اليمين" #: editor/editor_node.cpp #, fuzzy @@ -2803,11 +2780,11 @@ msgstr "النسخة:" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Set Up Version Control" -msgstr "" +msgstr "إعداد التØكم بالنسخة" #: editor/editor_node.cpp msgid "Shut Down Version Control" -msgstr "" +msgstr "إطÙاء التØكم بالنسخة Version Control" #: editor/editor_node.cpp #, fuzzy @@ -2816,7 +2793,7 @@ msgstr "تصدير" #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "تØميل قالب البناء للأندرويد..." #: editor/editor_node.cpp #, fuzzy @@ -2965,7 +2942,7 @@ msgstr "إعدادات المÙعدل" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "" +msgstr "اÙØªØ Ù…Ù„Ù Ø¨ÙŠØ§Ù†Ø§Øª المØرر" #: editor/editor_node.cpp #, fuzzy @@ -3011,7 +2988,7 @@ msgstr "إعادة إستيراد" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "إرسال مستندات التغذية الراجعة Feedback" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3031,7 +3008,7 @@ msgstr "تشغيل" #: editor/editor_node.cpp msgid "Pause the scene execution for debugging." -msgstr "" +msgstr "إيقا٠جلسة المشهد من أجل ØªÙ†Ù‚ÙŠØ Ø§Ù„ÙƒØ¨ÙˆØ§Øª البرمجية debugging." #: editor/editor_node.cpp msgid "Pause Scene" @@ -3059,7 +3036,7 @@ msgstr "تشغيل المشهد المخصص" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "تعديل معرّ٠الÙيديو video driver يتطلب إعادة تشغيل المØرر." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp @@ -3110,7 +3087,7 @@ msgstr "لا تØÙظ" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "قالب البناء الخاص بالأندرويد Ù…Ùقود، من Ùضلك نزل قوالب ذات صلة." #: editor/editor_node.cpp #, fuzzy @@ -3127,6 +3104,13 @@ msgid "" "the \"Use Custom Build\" option should be enabled in the Android export " "preset." msgstr "" +"بهذه الطريقة سيتم إعداد المشروع الخاص بك لأجل نسخ بناء أندريد مخصوصة عن طريق " +"تنزيل قوالب المصدر البرمجي ÙÙŠ \"res://android/build\".\n" +"يمكنك تطبيق تعديلات الخاصة على نسخة البناء للØصول على Øزمة تطبيق أندرويد APK " +"معدّلة عند التصدير (زيادة Ù…ÙÙ„Øقات، تعديل مل٠AndroidManifest.xml إلخ..).\n" +"ضع ÙÙŠ بالك أنه من أجل إنشاء نسخ بناء مخصوصة بدلاً من الØزم APKs المبنية سلÙاً، " +"ينبغي أن يكون إعداد \"استخدام بناء مخصص\" ممكناً ÙÙŠ إعدادات تصدير الأندرويد " +"Android export preset." #: editor/editor_node.cpp msgid "" @@ -3135,6 +3119,9 @@ msgid "" "Remove the \"res://android/build\" directory manually before attempting this " "operation again." msgstr "" +"إن قالب البناء الخاص بالأندرويد تم تنزيله سلÙاً لأجل هذا المشروع ولا يمكنه " +"الكتابة Ùوق البيانات السابقة.\n" +"قم بإزالة \"res://android/build\" يدوياً قبل الشروع بهذه العملية مرة أخرى." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3277,7 +3264,7 @@ msgstr "ذاتي" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "اطار #:" +msgstr "إطار #:" #: editor/editor_profiler.cpp msgid "Time" @@ -3285,32 +3272,31 @@ msgstr "الوقت" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "ندائات" +msgstr "إستدعاءات" #: editor/editor_properties.cpp -#, fuzzy msgid "Edit Text:" -msgstr "الأعضاء" +msgstr "تØرير النص:" #: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" -msgstr "" +msgstr "Ùعّال" #: editor/editor_properties.cpp msgid "Layer" -msgstr "" +msgstr "طبقة" #: editor/editor_properties.cpp msgid "Bit %d, value %d" -msgstr "" +msgstr "Bit %dØŒ القيمة %d" #: editor/editor_properties.cpp msgid "[Empty]" -msgstr "" +msgstr "[Ùارغ]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." -msgstr "" +msgstr "إلØاق..." #: editor/editor_properties.cpp #, fuzzy @@ -3322,12 +3308,15 @@ msgid "" "The selected resource (%s) does not match any type expected for this " "property (%s)." msgstr "" +"يلا يتطابق نوع المورد المختار (%s) مع أي نوع متوقع لأجل هذه الخاصية (%s)." #: editor/editor_properties.cpp msgid "" "Can't create a ViewportTexture on resources saved as a file.\n" "Resource needs to belong to a scene." msgstr "" +"لا يمكن إنشاء نقشة إطار العرض ViewportTexture على مورد تم ØÙظه كملÙ.\n" +"ينبغي أن ينتمي المورد إلى مشهد ما." #: editor/editor_properties.cpp msgid "" @@ -3336,14 +3325,18 @@ msgid "" "Please switch on the 'local to scene' property on it (and all resources " "containing it up to a node)." msgstr "" +"لا يمكن إنشاء نقشة إطار العرض ViewportTexture اعتماداً على هذا المصدر كونه " +"ليس Ù…Øلياً بالنسبة للمشهد.\n" +"قم بتشغيل خاصية 'Ù…Øلي بالنسبة للمشهد local to scene' لذلك المورد (ولكل " +"الموارد التي تضمنتها وصولاً إلى العقدة)." #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "" +msgstr "اختر إطار عرض" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" -msgstr "" +msgstr "نص برمجي جديد" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp #, fuzzy @@ -3352,7 +3345,7 @@ msgstr "ÙØªØ Ø§Ù„ÙƒÙˆØ¯" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "%s جديدة" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" @@ -3370,7 +3363,7 @@ msgstr "إجعلة مميزاً" #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "لصق" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Convert To %s" @@ -3378,20 +3371,20 @@ msgstr "تØويل إلي %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Selected node is not a Viewport!" -msgstr "" +msgstr "العÙقدة المختارة ليست إطار عرض Viewport!" #: editor/editor_properties_array_dict.cpp msgid "Size: " -msgstr "" +msgstr "الØجم: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "الصÙØØ©: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Item" -msgstr "" +msgstr "إزالة عنصر" #: editor/editor_properties_array_dict.cpp #, fuzzy @@ -3405,7 +3398,7 @@ msgstr "إسم جديد:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" +msgstr "إضاÙØ© زوج Ù…ÙتاØ/قيمة" #: editor/editor_run_native.cpp msgid "" @@ -3445,7 +3438,7 @@ msgstr "إختيار عقدة(عقد) للإستيراد" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "" +msgstr "تصÙØ" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -3475,7 +3468,7 @@ msgstr "تنزيل" #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." -msgstr "" +msgstr "قوالب التصدير الرسمية غير مدعومة لأجل البناء الخاص بالتطوير." #: editor/export_template_manager.cpp msgid "(Missing)" @@ -3520,11 +3513,13 @@ msgstr "يستورد:" #: editor/export_template_manager.cpp msgid "Error getting the list of mirrors." -msgstr "" +msgstr "هناك خطأ ÙÙŠ جلب قائمة المرايا mirrors." #: editor/export_template_manager.cpp msgid "Error parsing JSON of mirror list. Please report this issue!" msgstr "" +"Øدث خطأ ÙÙŠ ÙÙƒ (تÙسير parsing) مل٠JSON الخاص بقائمة المرايا. من Ùضلك بلّغ عن " +"هذه المشكلة!" #: editor/export_template_manager.cpp msgid "" @@ -3576,6 +3571,8 @@ msgid "" "Templates installation failed.\n" "The problematic templates archives can be found at '%s'." msgstr "" +"أخÙÙ‚ تنصيب القوالب.\n" +"يمكن إيجاد أرشي٠القوالب المعطوبة ÙÙŠ '%s'." #: editor/export_template_manager.cpp #, fuzzy @@ -3860,7 +3857,7 @@ msgstr "مل٠أو مجلد مع هذا الأسم موجود بالÙعل." #: editor/filesystem_dock.cpp msgid "Overwrite" -msgstr "" +msgstr "الكتابة المÙتراكبة Overwrite" #: editor/filesystem_dock.cpp #, fuzzy @@ -3869,7 +3866,7 @@ msgstr "ØÙظ المشهد" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "" +msgstr "إنشاء نص برمجي" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -3896,15 +3893,17 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"يتضمن الملÙات ذات الإضاÙات التالية. قم بإضاÙتهم أو إزالتهم ÙÙŠ إعدادات " +"المشروع." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find..." -msgstr "" +msgstr "ابØØ«..." #: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp msgid "Replace..." -msgstr "" +msgstr "استبدال..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" @@ -3975,7 +3974,7 @@ msgstr "إضاÙØ© إلي مجموعة" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp #: editor/scene_tree_editor.cpp msgid "Filter nodes" -msgstr "" +msgstr "العÙقد المÙرشØØ© Filter nodes" #: editor/groups_editor.cpp #, fuzzy @@ -3984,7 +3983,7 @@ msgstr "إضاÙØ© إلي مجموعة" #: editor/groups_editor.cpp msgid "Empty groups will be automatically removed." -msgstr "" +msgstr "ستزال المجموعات الÙارغة بصورة تلقائية." #: editor/groups_editor.cpp #, fuzzy @@ -4074,9 +4073,8 @@ msgid "Saving..." msgstr "جاري الØÙظ..." #: editor/import_dock.cpp -#, fuzzy msgid "%d Files" -msgstr " ملÙات" +msgstr "%d ملÙات" #: editor/import_dock.cpp msgid "Set as Default for '%s'" @@ -4101,16 +4099,16 @@ msgstr "إعادة إستيراد" #: editor/import_dock.cpp msgid "Save Scenes, Re-Import, and Restart" -msgstr "" +msgstr "اØÙظ المشاهد، إعادة-الإستيراد، وإعادة التشغيل" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." -msgstr "" +msgstr "يتطلب تعديل نوع الملÙات المستوردة إعادة تشغيل المØرر." #: editor/import_dock.cpp msgid "" "WARNING: Assets exist that use this resource, they may stop loading properly." -msgstr "" +msgstr "تØذير: هناك Ù…ÙÙ„Øقات تستخدم هذا المورد، ربما سيتوق٠تØميلها بشكل صØÙŠØ." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4219,19 +4217,19 @@ msgstr "إضاÙات" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "" +msgstr "المجلد الÙرعي:" #: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp msgid "Language:" -msgstr "" +msgstr "اللغة:" #: editor/plugin_config_dialog.cpp msgid "Script Name:" -msgstr "" +msgstr "اسم النص البرمجي:" #: editor/plugin_config_dialog.cpp msgid "Activate now?" -msgstr "" +msgstr "التÙعيل الآن؟" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -4320,6 +4318,7 @@ msgstr "تغيير وقت الدمج" #: editor/plugins/animation_state_machine_editor.cpp msgid "This type of node can't be used. Only root nodes are allowed." msgstr "" +"لا يمكن استخدام هذا النوع من العÙقد. Ùقط العÙقد الرئيسة root nodes مسموØØ©." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4334,13 +4333,12 @@ msgid "Add Animation Point" msgstr "أض٠Øركة" #: editor/plugins/animation_blend_space_1d_editor.cpp -#, fuzzy msgid "Remove BlendSpace1D Point" -msgstr "Ù…Ø³Ø Ø§Ù„Ø¨ÙˆÙ„ÙŠ والنقطة" +msgstr "إزالة نقطة BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Move BlendSpace1D Node Point" -msgstr "" +msgstr "Øرك نقطعة العÙقدة BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4350,95 +4348,92 @@ msgid "" "AnimationTree is inactive.\n" "Activate to enable playback, check node warnings if activation fails." msgstr "" +"شجرة الرسومات المتØركة غير Ùعالة.\n" +"Ùعلها لتتمكن من التشغيل playbackØŒ تÙقد التنبيه الذي تصدره العÙقدة إن Ùشل " +"التÙعيل." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Set the blending position within the space" -msgstr "" +msgstr "Øدد مكان الخلط blending position ضمن الÙراغ" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Select and move points, create points with RMB." -msgstr "" +msgstr "Øدد ÙˆØرك النقاط، أنشئ النقاط باستخدام RMB." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp +#, fuzzy msgid "Enable snap and show grid." -msgstr "" +msgstr "تمكين المØاذاة وإظهار الشبكة." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Point" -msgstr "" +msgstr "نقطة" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Open Editor" -msgstr "ÙØªØ Ø§Ù„Ù…Ùعدل 2D" +msgstr "ÙØªØ Ø§Ù„Ù…ÙØرر ثنائي الأبعاد 2D" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Open Animation Node" -msgstr "عقدة الØركة" +msgstr "ÙØªØ Ø¹Ùقدة الرسم المتØرك Animation" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "خطأ: إسم الØركة موجود بالÙعل!" +msgstr "المثلثات موجودة سلÙاً." #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Triangle" -msgstr "إضاÙØ© مسار" +msgstr "إضاÙØ© مثلث" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Change BlendSpace2D Limits" -msgstr "تغيير وقت الدمج" +msgstr "تغيير Øدود(إمكانيات) BlendSpace2D \"الدمج_الÙضائي_ثنائي البÙعد\"" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Change BlendSpace2D Labels" -msgstr "تغيير وقت الدمج" +msgstr "تعديل لصاقات BlendSpace2D \"الدمج الÙضائي ثنائي البÙعد\"" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Remove BlendSpace2D Point" -msgstr "Ù…Ø³Ø Ø§Ù„Ø¨ÙˆÙ„ÙŠ والنقطة" +msgstr "إزالة نقاط الدمج الÙضائي ثنائي البÙعد BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Remove BlendSpace2D Triangle" -msgstr "" +msgstr "إزالة مثلث الدمج الÙضائي ثنائي البÙعد BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "BlendSpace2D does not belong to an AnimationTree node." msgstr "" +"إن BlendSpace2D لا ينتمي إلى عÙقدة شجرة الرسومات المتØركة AnimationTree." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "No triangles exist, so no blending can take place." -msgstr "" +msgstr "لا وجود لأي من المثلثات، لذا لا يمكن أن يتم الخلط." #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Toggle Auto Triangles" -msgstr "تبديل التØميل التلقائي العام" +msgstr "تÙعيل المثلثات التلقائية" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create triangles by connecting points." -msgstr "" +msgstr "إنشاء المثلثات عن طريق وصل النقاط." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Erase points and triangles." -msgstr "" +msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø· والمثلثات." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Generate blend triangles automatically (instead of manually)" -msgstr "" +msgstr "توليد مثلثات دمج بصورة تلقائية (بدلاً من اليدوية)" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -4446,78 +4441,73 @@ msgid "Blend:" msgstr "الدمج:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Parameter Changed" -msgstr "تØديث التغييرات" +msgstr "لقد تم تغيير المَعلم" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Filters" -msgstr "تعديل المصاÙÙŠ" +msgstr "تعديل المÙرشØات" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Output node can't be added to the blend tree." -msgstr "" +msgstr "لا يمكن إضاÙØ© عÙقدة المخرجات إلى شجرة الدمج." #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Add Node to BlendTree" -msgstr "" +msgstr "إضاÙØ© عÙقدة إلى شجرة الدمج BlendTree" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Node Moved" -msgstr "وضع التØريك" +msgstr "لقد تØركت العÙقدة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Unable to connect, port may be in use or connection may be invalid." msgstr "" +"غير قادر على الاتصال، ربما البوابة قيد الاستخدام أو أن الإتصال غير صالØ." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Nodes Connected" -msgstr "متصل" +msgstr "العÙقد متصلة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Nodes Disconnected" -msgstr "غير متصل" +msgstr "العÙقد غير متصلة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Set Animation" -msgstr "صورة متØركة" +msgstr "تØديد الرسومية المتØركة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Node" -msgstr "إنشاء عقدة" +msgstr "Øذ٠العÙقدة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "" +msgstr "Øذ٠عÙقدة (عÙقد)" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Toggle Filter On/Off" -msgstr "تمكين/إيقا٠هذا المسار." +msgstr "تعديل المÙرشØات تشغيل/إيقاÙ" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Change Filter" -msgstr "تغيير خط الØركة" +msgstr "تغيير المÙØ±Ø´Ø Filter" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." msgstr "" +"لم يتم تØديد أي من الرسومات المتØركة للاعب، لذا لا يمكن استرجاع أسماء " +"المقاطع." #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Player path set is invalid, so unable to retrieve track names." -msgstr "" +msgstr "المسار المØدد للاعب غير مناسب، لا يمكن استرجاع أسماء المقاطع." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp @@ -4525,43 +4515,39 @@ msgid "" "Animation player has no valid root node path, so unable to retrieve track " "names." msgstr "" +"الرسومات المتØركة الخاصة باللاعب لا تملك مسار عÙقدة صالØØŒ غير قادر على " +"استرجاع أسماء المقاطع." #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Anim Clips" -msgstr "مقاطع الرسوم المتØركة:" +msgstr "مقاطع الرسوم المتØركة" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Audio Clips" -msgstr "مقاطع صوتية:" +msgstr "مقاطع صوتية" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Functions" -msgstr "الإعدادات:" +msgstr "الوظائ٠البرمجية" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Renamed" -msgstr "إسم العقدة:" +msgstr "العÙقدة معادة التسمية" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add Node..." -msgstr "" +msgstr "إضاÙØ© عÙقدة..." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp -#, fuzzy msgid "Edit Filtered Tracks:" -msgstr "تعديل المصاÙÙŠ" +msgstr "تØرير المقاطع المÙرشØØ© Filtered Tracks:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "تغيير خط الØركة" +msgstr "تمكين Ø§Ù„ØªØ±Ø´ÙŠØ Filtering" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4621,27 +4607,24 @@ msgid "Duplicate Animation" msgstr "تكرير الØركة" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to copy!" -msgstr "خطأ: لا Øركة لنسخها!" +msgstr "لا Øركة رسومية لنسخها!" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation resource on clipboard!" -msgstr "خطأ: لا مصدر Øركة علي الØاÙظة!" +msgstr "لا يوجد مورد لرسومية متØركة ÙÙŠ الØاÙظة clipboard!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "Øركة Ù…Ùلصقة" +msgstr "الØركة الرسومية المÙلصقة" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "لصق الØركة" +msgstr "لصق الرسوم المتØركة" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to edit!" -msgstr "خطأ: لا Øركة لتعديلها!" +msgstr "لا رسومات متØركة لتØريرها!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" @@ -4680,14 +4663,12 @@ msgid "Animation" msgstr "صورة متØركة" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Edit Transitions..." -msgstr "تØويلات" +msgstr "تØرير الانتقالات..." #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Open in Inspector" -msgstr "Ù…Ùراقب" +msgstr "اÙØªØ ÙÙŠ المÙتصÙØ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." @@ -4702,9 +4683,8 @@ msgid "Enable Onion Skinning" msgstr "تÙعيل تقشير البصل" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "تقشير البصل" +msgstr "إعدادت Ø´ÙاÙية طبقات البصل" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4724,7 +4704,7 @@ msgstr "العمق" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "الخطوة 1" +msgstr "خطوة واØدة" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" @@ -4747,9 +4727,8 @@ msgid "Include Gizmos (3D)" msgstr "تضمين جيزموس (3D)" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Pin AnimationPlayer" -msgstr "لصق الØركة" +msgstr "تثبيت Ù…Ùشغّل الرسوميات المتØركة" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" @@ -4779,48 +4758,45 @@ msgid "Cross-Animation Blend Times" msgstr "وقت الدمج عبر الØركة" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Move Node" -msgstr "وضع التØريك" +msgstr "تØريك العÙقدة" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition exists!" -msgstr "تØول" +msgstr "الإنتقال موجود سلÙاً!" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Add Transition" -msgstr "تØول" +msgstr "إضاÙØ© انتقال" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "" +msgstr "إضاÙØ© عÙقدة" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "النهاية" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Ùوري" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "مزامنة" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "ÙÙŠ النهاية" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "السÙر" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." -msgstr "" +msgstr "عÙقد البداية والنهاية مطلوبة لأجل الانتقال الجزيئ sub-transition." #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4839,7 +4815,7 @@ msgstr "عقدة التنقل" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" -msgstr "" +msgstr "تØديد عÙقدة البداية (التشغيل التلقائي)" #: editor/plugins/animation_state_machine_editor.cpp msgid "" @@ -4847,6 +4823,9 @@ msgid "" "RMB to add new nodes.\n" "Shift+LMB to create connections." msgstr "" +"اختر ÙˆØرّك العÙقد.\n" +"RMB (زر الÙأرة الأيمن) لإضاÙØ© عÙقد جديدة.\n" +"LMB + Shift (زر الÙأرة الأيسر) لإنشاء الوصلات." #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4866,10 +4845,13 @@ msgstr "ازالة المسار المØدد." #: editor/plugins/animation_state_machine_editor.cpp msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" +"تبديل (نعم/لا) التشغيل التلقائي لهذا الرسم المتØرك ليشتغل، يعيد التشغيل، أو " +"يسعى للصÙر." #: editor/plugins/animation_state_machine_editor.cpp msgid "Set the end animation. This is useful for sub-transitions." msgstr "" +"تØديد الرسومية المتØركة الخاصة بالنهاية. سيكون ذلك Ù…Ùيداً للØركات الÙرعية." #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -5062,7 +5044,7 @@ msgstr "لا يمكن المسØ:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Write error." -msgstr "" +msgstr "كتابة خطأ." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" @@ -5144,19 +5126,19 @@ msgstr "تØميل هذا الأصل قيد التنÙيذ أصلاً!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Recently Updated" -msgstr "" +msgstr "ØÙدّث منذ Ùترة وجيزة" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Least Recently Updated" -msgstr "" +msgstr "آخر تØديث قريب الأمد" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (A-Z)" -msgstr "" +msgstr "الاسم (أل٠بائياً)" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (Z-A)" -msgstr "" +msgstr "الاسم (ترتيب أل٠بائي معكوس)" #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5184,7 +5166,7 @@ msgstr "التالي" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Last" -msgstr "" +msgstr "الأخير" #: editor/plugins/asset_library_editor_plugin.cpp msgid "All" @@ -5192,7 +5174,7 @@ msgstr "الكل" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No results for \"%s\"." -msgstr "" +msgstr "لا نتائج من أجل \"%s\"." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy @@ -5263,12 +5245,12 @@ msgstr "لا يمكن انشاء خرائط الضوء, تاكد من ان ال٠#: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "اعداد خرائط الضوء" +msgstr "إعداد خرائط الضوء" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp msgid "Preview" -msgstr "إستعراض" +msgstr "استعراض" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" @@ -5284,12 +5266,11 @@ msgstr "خطوة الشبكة:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Primary Line Every:" -msgstr "" +msgstr "الأخط الأولي ÙƒÙÙ„:" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "steps" -msgstr "خطوتان" +msgstr "خطوات" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" @@ -5300,42 +5281,34 @@ msgid "Rotation Step:" msgstr "خطوة الدوران:" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale Step:" -msgstr "تكبير/تصغير:" +msgstr "خطوة التØجيم:" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move Vertical Guide" msgstr "تØريك الموجه العمودي" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Vertical Guide" msgstr "إنشاء موجه عمودي جديد" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove Vertical Guide" msgstr "Ù…Ø³Ø Ø§Ù„Ù…ÙˆØ¬Ù‡ العمودي" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move Horizontal Guide" msgstr "تØريك الموجه الأÙقي" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Horizontal Guide" msgstr "إنشاء موجه Ø£Ùقي جديد" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove Horizontal Guide" msgstr "Ù…Ø³Ø Ø§Ù„Ù…ÙˆØ¬Ù‡ الأÙقي" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Horizontal and Vertical Guides" msgstr "إنشاء موجه عمودي وأÙقي جديد" @@ -5378,85 +5351,76 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"عندما يكون Ùعالاً، إن تØريك عÙقد التØكم سيغير نقطة التثبيت anchors الخاص بها " +"بدلاً من الهوامش." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Left" -msgstr "وضع التدوير" +msgstr "ÙÙŠ الأعلى يساراً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Right" -msgstr "وضع التدوير" +msgstr "ÙÙŠ الأعلى يميناً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Right" -msgstr "وضع التدوير" +msgstr "ÙÙŠ الأسÙÙ„ يميناً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Left" -msgstr "وضع التدوير" +msgstr "ÙÙŠ الأسÙÙ„ يساراً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Left" -msgstr "نص٠المÙØدد" +msgstr "ÙÙŠ المنتص٠يساراً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Top" -msgstr "نص٠المÙØدد" +msgstr "ÙÙŠ أعلى المنتصÙ" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Right" -msgstr "وضع التدوير" +msgstr "ÙÙŠ المنتص٠يميناً" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Bottom" -msgstr "نص٠المÙØدد" +msgstr "ÙÙŠ أسÙÙ„ المنتصÙ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" -msgstr "" +msgstr "المنتصÙ" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Left Wide" -msgstr "الخط الشمالي" +msgstr "بالعرض يساراً" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Top Wide" -msgstr "" +msgstr "بالعرض بالأعلى" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Right Wide" -msgstr "الخط اليميني" +msgstr "بالعرض يميناً" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Bottom Wide" -msgstr "" +msgstr "بالعرض بالأسÙÙ„" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "VCenter Wide" -msgstr "" +msgstr "بالعرض بالمنتص٠شاقولياً" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "HCenter Wide" -msgstr "" +msgstr "بالعرض بالمنتص٠أÙقياً" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Full Rect" -msgstr "" +msgstr "على كامل المستطيل" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Keep Ratio" -msgstr "نسبة التكبير:" +msgstr "نسبة التكبير" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -5476,6 +5440,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" +"تجاوز كاميرا اللعبة.\n" +"تجاوز كاميرا اللعبة عن طريق كاميرا إطار العرض ÙÙŠ المØرر." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5483,48 +5449,44 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" +"تجاوز كاميرا اللعبة.\n" +"ليس هناك لعبة منمذجة قيد التشغيل." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Øدد" +msgstr "ØÙدد القÙÙ„" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock Selected" -msgstr "" +msgstr "ØÙدد إلغاء القÙÙ„" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Øذ٠المÙØدد" +msgstr "ØÙدد التجميع" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Øذ٠المÙØدد" +msgstr "ØÙدد إلغاء التجميع" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "لصق الوضع" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Guides" -msgstr "إخلاء الوضع" +msgstr "Ù…Ø³Ø Ø§Ù„Ù…ÙˆØ¬Ù‡Ø§Øª" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "أنشئ نقاط إنبعاث من الشبكة" +msgstr "إنشاء عظمة (عظام) مخصوصة من عÙقدة (عÙقد)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "إخلاء الوضع" +msgstr "Ù…Ø³Ø Ø§Ù„Ø¹Ø¸Ø§Ù…" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5579,9 +5541,8 @@ msgstr "وضع التدوير" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scale Mode" -msgstr "تØديد الوضع" +msgstr "وضع التØجيم" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5601,91 +5562,77 @@ msgid "Pan Mode" msgstr "وضع السØب" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Ruler Mode" -msgstr "تØديد الوضع" +msgstr "وضع المسطرة" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle smart snapping." -msgstr "إلغاء/تÙعيل الكبس" +msgstr "إلغاء/تÙعيل Ù…Øاذاة الشبكة بذكاء." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Use Smart Snap" -msgstr "إستخدم الكبس" +msgstr "استخدام المØاذاة الذكية" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle grid snapping." -msgstr "إلغاء/تÙعيل الكبس" +msgstr "إلغاء/تÙعيل المØاذاة للشبكة." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Use Grid Snap" -msgstr "إستخدم الكبس" +msgstr "استخادم المØاذاة للشبكة" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snapping Options" -msgstr "إعدادات الكبس" +msgstr "إعدادت المØاذاة" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" -msgstr "إستعمال كبس التدوير" +msgstr "استعمال Ù…Øاذاة التدوير" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Use Scale Snap" -msgstr "إستخدم الكبس" +msgstr "استخدام Ù…Øاذاة التØجيم" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" -msgstr "نسبية الكبس" +msgstr "نسبية المØاذاة" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Pixel Snap" msgstr "إستخدام كبس البكسل" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "الكبس الذكي" +msgstr "المØاذاة الذكية" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Configure Snap..." -msgstr "تعديل الكبس..." +msgstr "تعديل المØاذاة..." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "الكبس إلي الطÙÙ„" +msgstr "المØاذاة بالنسبة للأصل Parent" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "إكبس إلي مرتكز العقدة" +msgstr "Øاذي إلي مرتكز العقدة" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "إكبس إلي جوانب العقدة" +msgstr "Øاذي إلي جوانب العقدة" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "إكبس إلي مرتكز العقدة" +msgstr "Øاذي إلي Ù…Ùنتص٠العقدة" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "إكبس إلي العقد الأخري" +msgstr "Øاذي إلى العقد الأخرى" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "أكبس إلي الموجهات" +msgstr "Øاذي إلى الموجهات" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5708,9 +5655,8 @@ msgid "Restores the object's children's ability to be selected." msgstr "إرجاع مقدرة تØديد الطÙÙ„ للعنصر." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Skeleton Options" -msgstr "الÙردية" +msgstr "إعدادات الهكيل العظمي" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" @@ -5718,12 +5664,11 @@ msgstr "إظهار العظام" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make Custom Bone(s) from Node(s)" -msgstr "" +msgstr "إنشاء عظمة (عظام) مخصوصة من عÙقدة (عÙقد)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Custom Bones" -msgstr "إخلاء العظام" +msgstr "Ù…Ø³Ø Ø§Ù„Ø¹Ø¸Ø§Ù… المخصوصة" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5731,9 +5676,8 @@ msgid "View" msgstr "أظهر" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Always Show Grid" -msgstr "إظهار الشبكة" +msgstr "إظهار الشبكة دوماً" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5757,7 +5701,7 @@ msgstr "أظهر الشاشة" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" -msgstr "" +msgstr "إظهار أيقونات المجوعة والقÙÙ„" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" @@ -5769,19 +5713,19 @@ msgstr "إملئ الشاشة بالمØدد" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "إظهار تØجيم اللوØØ© Canvas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." -msgstr "" +msgstr "قناع الترجمة لأجل إدخال المÙاتيØ." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "" +msgstr "قناع التدوير لأجل إدخال المÙاتيØ." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." -msgstr "" +msgstr "قناع التØجيم لأجل إدخال المÙاتيØ." #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5795,16 +5739,18 @@ msgid "" "Keys are only added to existing tracks, no new tracks will be created.\n" "Keys must be inserted manually for the first time." msgstr "" +"إدخال تلقائي للمÙØ§ØªÙŠØ Ø¹Ù†Ø¯Ù…Ø§ تترجم، تÙدار أو تØجم الأشياء objects (بناء على " +"القناع).\n" +"تÙضا٠المÙØ§ØªÙŠØ Ùقط للمقاطع الموجودة سلÙاً، Ùلا يتم إنشاء مقاطع جديدة.\n" +"يجب إدخال المÙØ§ØªÙŠØ ÙŠØ¯ÙˆÙŠØ§Ù‹ ÙÙŠ أول مرة." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Auto Insert Key" -msgstr "أض٠مÙØªØ§Ø Ø§Ù„Øركة" +msgstr "Ù…ÙØªØ§Ø Ù…Ùدخل بصورة تلقائية" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Animation Key and Pose Options" -msgstr "مدة الØركة (seconds)" +msgstr "إعدادت المÙØªØ§Ø ÙˆØ§Ù„ÙˆØ¶Ø¹ÙŠØ© للرسومات المتØركة" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -5867,17 +5813,16 @@ msgstr "" "سØب Ùˆ إسقاط + Alt : تغيير نوع العقدة" #: editor/plugins/collision_polygon_editor_plugin.cpp -#, fuzzy msgid "Create Polygon3D" -msgstr "إنشاء بولي" +msgstr "إنشاء متعدد Ø³Ø·ÙˆØ Ø«Ù„Ø§Ø«ÙŠ الأبعاد" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" -msgstr "تعديل البولي" +msgstr "تعديل Ù…Ùتعدد السطوØ" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "تعديل البولي (Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©)" +msgstr "تعديل متعدد Ø§Ù„Ø³Ø·ÙˆØ (Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" @@ -5892,14 +5837,13 @@ msgstr "Øمل قناع الانبعاث" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Restart" -msgstr "إعادة تشغيل (ثواني):" +msgstr "إعادة التشغيل" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" -msgstr "Ø¥Ù…Ø³Ø Ù‚Ù†Ø§Ø¹ الانبعاث" +msgstr "Ø§Ù…Ø³Ø Ù‚Ù†Ø§Ø¹ الانبعاث" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5920,18 +5864,17 @@ msgstr "قناع الانبعاث" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Solid Pixels" -msgstr "" +msgstr "البكسيلات الأساسية Solid Pixels" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Border Pixels" -msgstr "" +msgstr "البكسلات المØيطية (الØدودية)" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Directed Border Pixels" -msgstr "الوجهات والملÙات:" +msgstr "البكسلات المØيطية (الØدودية) الموجهة" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5959,22 +5902,20 @@ msgid "Create Emission Points From Node" msgstr "أنشئ نقاط إنبعاث من العقدة" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "مسطØ0" +msgstr "Ø§Ù„Ø³Ø·Ø 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "مسطØ1" +msgstr "Ø§Ù„Ø³Ø·Ø 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "" +msgstr "دخول متسارع Ease In" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "" +msgstr "تراجع Ù…Ùتباطئ Ease Out" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" @@ -5982,7 +5923,7 @@ msgstr "خطوة ناعمة" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "نعديل نقطة الإنØناء" +msgstr "تعديل نقطة الإنØناء" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" @@ -5993,22 +5934,18 @@ msgid "Load Curve Preset" msgstr "تØميل إعداد مسبق للإنØناء" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "إضاÙØ© نقطة" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "الخط الشمالي" +msgstr "الخط اليساري" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "الخط اليميني" @@ -6027,12 +5964,11 @@ msgstr "إلغاء/تÙعيل مماس خط المنØني" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "إبقي ضاغطاً علي Shift لتعديل المماس Ùردياً" +msgstr "إبقى ضاغطاً على Shift لتعديل المماس Ùردياً" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right click to add point" -msgstr "إظغط: أض٠نقطة" +msgstr "اضغط بالزر الأيمن لإضاÙØ© نقطة" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" @@ -6040,7 +5976,7 @@ msgstr "طبخ مجس GI" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" -msgstr "" +msgstr "التدرج المÙØرر" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -6063,9 +5999,8 @@ msgid "Mesh is empty!" msgstr "الميش Ùارغ!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create a Trimesh collision shape." -msgstr "إنشاء متصادم تراميش قريب" +msgstr "لا يمكن إنشاء شكل Trimesh تصادمي." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" @@ -6073,47 +6008,43 @@ msgstr "أنشئ جسم تراميش ثابت" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" -msgstr "هذا لا يعمل علي جزر المشهد!" +msgstr "لا يعمل هذا على المشهد الرئيس!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "أنشئ شكل تراميش" +msgstr "أنشئ شكل Trimesh ساكن" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create a single convex collision shape for the scene root." -msgstr "" +msgstr "لا يمكن إنشاء شكل تصادمي Ù…ÙØدب لأجل المشهد الرئيس." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a single convex collision shape." -msgstr "" +msgstr "لم يتم إنشاء شكل Ù…Øدب تصادمي ÙˆØيد." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Shape" -msgstr "أنشئ شكل Ù…Øدب" +msgstr "أنشئ شكل Ù…Øدب ÙˆØيد" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create multiple convex collision shapes for the scene root." -msgstr "" +msgstr "لا يمكن إنشاء أشكال تصادم Ù…Øدبة عديدة لأجل المشهد الرئيس." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create any collision shapes." -msgstr "لا يمكن إنشاء المجلد." +msgstr "لا يمكن إنشاء أي شكل تصادمي." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Shapes" -msgstr "أنشئ شكل Ù…Øدب" +msgstr "أنشئ أشكال Ù…Øدبة متعددة" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "أنشئ ميش التنقل" +msgstr "أنشئ Ø³Ø·Ø Mesh التنقل" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "الميش المتضمن ليس من النوع الميش المتعدد." +msgstr "Ø§Ù„Ø³Ø·Ø Ø§Ù„Ù…ØªØ¶Ù…Ù† ليس نوعاً من مصÙÙˆÙØ© Ø§Ù„Ø³Ø·ÙˆØ ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" @@ -6161,6 +6092,8 @@ msgid "" "automatically.\n" "This is the most accurate (but slowest) option for collision detection." msgstr "" +"إنشاء جسم سكوني وقرنه مع جسم تصادمي شبيه بالمÙضلع تلقائياً.\n" +"هذا الخيار هو الأÙضل والأكثر دقة (ولكنه الأبطئ) لأجل الكش٠عن وجود تصادمات." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" @@ -6171,6 +6104,8 @@ msgid "" "Creates a polygon-based collision shape.\n" "This is the most accurate (but slowest) option for collision detection." msgstr "" +"إنشاء شكل تصادمي Ù…Ùضلعي الشكل.\n" +"هذا هو الخيار الأكثر دقة (لكنه الأبطئ) لأجل للكش٠عن وقوع التصادم." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -6182,6 +6117,8 @@ msgid "" "Creates a single convex collision shape.\n" "This is the fastest (but least accurate) option for collision detection." msgstr "" +"إنشاء شكل تصادمي ذو تØدب ÙˆØيد.\n" +"هذا هو الخيار الأسرع (لكنه الأقل دقة) للكش٠عن وقوع التصادم." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -6193,6 +6130,8 @@ msgid "" "Creates a polygon-based collision shape.\n" "This is a performance middle-ground between the two above options." msgstr "" +"إنشاء شكل تصادمي Ù…Ùضلعي الهيئة.\n" +"هذا الخيار \\Ù…Ùتوسط الأداء بين الخيارين أعلاه." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -6228,7 +6167,7 @@ msgstr "Øجم الخطوط:" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Channel Debug" -msgstr "" +msgstr "Ù…Ù†Ù‚Ø Ø£Ø®Ø·Ø§Ø¡ قناة UV" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove item %d?" @@ -6386,7 +6325,7 @@ msgstr "وقت التوليد (تانية):" #: editor/plugins/particles_editor_plugin.cpp msgid "The geometry's faces don't contain any area." -msgstr "" +msgstr "الوجوه الهندسية لا تتضمن أي منطقة." #: editor/plugins/particles_editor_plugin.cpp #, fuzzy @@ -6395,7 +6334,7 @@ msgstr "العقدة لا تØتوي على هندسة (الوجوه)." #: editor/plugins/particles_editor_plugin.cpp msgid "\"%s\" doesn't inherit from Spatial." -msgstr "" +msgstr "\"%s\" لا يرث الÙراغي Spatial." #: editor/plugins/particles_editor_plugin.cpp #, fuzzy @@ -6421,7 +6360,7 @@ msgstr "نقاط المساØØ©" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" -msgstr "" +msgstr "نقاط Ø§Ù„Ø³Ø·Ø + طبيعي (Ù…Ùوجّه)" #: editor/plugins/particles_editor_plugin.cpp msgid "Volume" @@ -6498,31 +6437,31 @@ msgstr "إظغط: أض٠نقطة" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Left Click: Split Segment (in curve)" -msgstr "" +msgstr "بالزر الأيسر: Ùصل القطعة (من المنØنى)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Right Click: Delete Point" -msgstr "" +msgstr "بالزر الأيمن: اØذ٠النقطة" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Select Control Points (Shift+Drag)" -msgstr "" +msgstr "اختر العÙقد الآباء (بالسØب + Shift)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Add Point (in empty space)" -msgstr "" +msgstr "إضاÙØ© عÙقدة (ÙÙŠ ÙÙسØØ© Ùارغة)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Delete Point" -msgstr "" +msgstr "اØذ٠النقطة" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Close Curve" -msgstr "" +msgstr "إغلاق المنØنى" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp @@ -6533,16 +6472,16 @@ msgstr "الإعدادات" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Angles" -msgstr "" +msgstr "زوايا مقبض المرآة" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Lengths" -msgstr "" +msgstr "أطول مقابض المرآة" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" -msgstr "" +msgstr "Ù†Ùقطة المنØنى #" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve Point Position" @@ -6558,11 +6497,11 @@ msgstr "Øدد موقع خروج الإنØناء" #: editor/plugins/path_editor_plugin.cpp msgid "Split Path" -msgstr "" +msgstr "Ùصل المسار" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "" +msgstr "إزالة Ù†Ùقطة المسار" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Out-Control Point" @@ -6570,367 +6509,346 @@ msgstr "Ù…Ø³Ø Ù†Ù‚Ø·Ø© خروج التØكم" #: editor/plugins/path_editor_plugin.cpp msgid "Remove In-Control Point" -msgstr "" +msgstr "إزالة النÙقطة داخلية التØكم In-Control" #: editor/plugins/path_editor_plugin.cpp msgid "Split Segment (in curve)" -msgstr "" +msgstr "Ùصل القطعة (من المÙÙ†Øنى)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "تØريك النÙقطة" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "The skeleton property of the Polygon2D does not point to a Skeleton2D node" msgstr "" +"إن خاصية الهيكل الخاص بالمضلع ثنائي الأبعاد لا تشير إلى عÙقدة هيكلية ثنائية " +"الأبعاد Skeleton2D" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Sync Bones" -msgstr "إظهار العظام" +msgstr "Ù…Ùزامنة العظام" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "No texture in this polygon.\n" "Set a texture to be able to edit UV." msgstr "" +"لا نقوش ÙÙŠ هذا المÙضلع.\n" +"Øدد نقشاً لتتمكن من تعديل UV." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" -msgstr "" +msgstr "إنشاء خريطة UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "Polygon 2D has internal vertices, so it can no longer be edited in the " "viewport." msgstr "" +"يمتلك المÙضلع ثنائي الأبعاد رؤوساً داخلياً، لذا لا يمكن الاستمرار بتعديله ÙÙŠ " +"إطار العرض." #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Polygon & UV" -msgstr "إنشاء بولي" +msgstr "إنشاء Ù…Ùضلع ÙˆUV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Internal Vertex" -msgstr "إنشاء موجه Ø£Ùقي جديد" +msgstr "إنشاء رأس داخلي" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Remove Internal Vertex" -msgstr "Ù…Ø³Ø Ø§Ù„Ù…ÙˆØ¬Ù‡ العمودي" +msgstr "إزالة الرأس الداخلي" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Invalid Polygon (need 3 different vertices)" -msgstr "" +msgstr "Ù…Ùضلع غير ØµØ§Ù„Ø (ÙŠØتاج لثلاثة رؤوس مختلÙØ©)" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Add Custom Polygon" -msgstr "تعديل البولي" +msgstr "إضاÙØ© Ù…Ùضلع مخصوص" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Remove Custom Polygon" -msgstr "Ù…Ø³Ø Ø§Ù„Ø¨ÙˆÙ„ÙŠ والنقطة" +msgstr "إزالة المÙضلع المخصوص" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Transform UV Map" -msgstr "" +msgstr "إعادة تشكيل خريطة UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Transform Polygon" -msgstr "إنشاء بولي" +msgstr "إعادة تشكيل المÙضلع" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint Bone Weights" -msgstr "" +msgstr "طلاء العظام وزنياً" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Open Polygon 2D UV editor." -msgstr "ÙØªØ Ø§Ù„Ù…Ùعدل 2D" +msgstr "ÙØªØ Ù…ÙØرر UV الخاص بالمÙضلعات ثنائية البÙعد." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" -msgstr "" +msgstr "Ù…ÙØرر UV الخاص بالمÙضلعات ثنائية البÙعد" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" -msgstr "" +msgstr "ال UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Points" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "النقاط" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Polygons" -msgstr "تعديل البولي" +msgstr "المÙضلعات" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Bones" -msgstr "أنشئ عظام" +msgstr "العظام" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Move Points" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "تØريك النقاط" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Ctrl: Rotate" -msgstr "" +msgstr "Ctrl: تدوير" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" -msgstr "" +msgstr "Shift: تØريك الكÙÙ„" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift+Ctrl: Scale" -msgstr "" +msgstr "Shift+Ctrl: تØجيم" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Polygon" -msgstr "" +msgstr "تØريك المÙضلع" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Rotate Polygon" -msgstr "" +msgstr "تدوير المÙضلع" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" -msgstr "" +msgstr "تØجيم المÙضلع" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create a custom polygon. Enables custom polygon rendering." -msgstr "" +msgstr "إنشاء Ù…Ùضلع مخصوص. تمكين إخراج المÙضلع المخصوص بصرياً." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "Remove a custom polygon. If none remain, custom polygon rendering is " "disabled." msgstr "" +"إزالة المÙضلع المخصوص. إن لم يتبق شيء، سيتم تعطيل إخراج المÙضلع المخصوص بصرياً." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint weights with specified intensity." -msgstr "" +msgstr "طلاء الأوزان بشدات Ù…Øددة." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Unpaint weights with specified intensity." -msgstr "" +msgstr "إزالة طلاء الأوزان بشدات Ù…Øددة." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Radius:" -msgstr "" +msgstr "نص٠القطر:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" -msgstr "" +msgstr "Ù…Ùضلع > UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV->Polygon" -msgstr "" +msgstr "UV > Ù…Ùضلع" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" -msgstr "" +msgstr "إزالة UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Settings" -msgstr "إعدادات المÙعدل" +msgstr "إعدادات الشبكة" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Snap" -msgstr "" +msgstr "Ù…Øاذاة" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "" +msgstr "تمكين المØاذاة" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" -msgstr "" +msgstr "الشبكة" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" msgstr "إظهار الشبكة" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Configure Grid:" -msgstr "تعديل اللقطة" +msgstr "تهيئة الشكبة:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset X:" -msgstr "معادل الشبكة:" +msgstr "معادل الشبكة على المØور الأÙقي X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset Y:" -msgstr "معادل الشبكة:" +msgstr "معادل الشبكة على المØور Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step X:" -msgstr "خطوة الشبكة:" +msgstr "خطوة الشبكة على المØور X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step Y:" -msgstr "خطوة الشبكة:" +msgstr "خطوة الشبكة على المØور Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Sync Bones to Polygon" -msgstr "" +msgstr "مزامنة العظام مع المÙضلع" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" -msgstr "" +msgstr "خطأ: لا يمكن تØميل المورد!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Add Resource" -msgstr "" +msgstr "إضاÙØ© مورد" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Rename Resource" -msgstr "" +msgstr "إعادة تسمية المورد" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Resource" -msgstr "" +msgstr "Øذ٠المورد" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Resource clipboard is empty!" -msgstr "" +msgstr "ØاÙظة الموارد Ùارغة!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Paste Resource" -msgstr "لصق الموارد" +msgstr "لصق المورد" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_editor.cpp msgid "Instance:" -msgstr "" +msgstr "نمذجة:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp #: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Type:" -msgstr "" +msgstr "نوع:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Open in Editor" -msgstr "" +msgstr "اÙØªØ ÙÙŠ المÙØرر" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Load Resource" -msgstr "" +msgstr "تØميل المورد" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ResourcePreloader" -msgstr "Ù…Øدث مسبق للموارد" +msgstr "مورد Ù…Øمل سلÙاً" #: editor/plugins/root_motion_editor_plugin.cpp msgid "AnimationTree has no path set to an AnimationPlayer" -msgstr "" +msgstr "لا تملك شجرة الرسومات المتØركة مساراً لمشغل الرسومات المتØركة" #: editor/plugins/root_motion_editor_plugin.cpp -#, fuzzy msgid "Path to AnimationPlayer is invalid" -msgstr "شجرة الØركة خاطئة." +msgstr "المسار لمشغل الرسومات المتØركة غير صالØ" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "" +msgstr "إزالة الملÙات الØديثة" #: editor/plugins/script_editor_plugin.cpp msgid "Close and save changes?" -msgstr "" +msgstr "الإغلاق مع ØÙظ التعديلات؟" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error writing TextFile:" -msgstr "خطأ ÙÙŠ ØÙظ مجموعة البلاط!" +msgstr "خطأ ÙÙŠ كتابة المل٠النصي TextFile:" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Could not load file at:" -msgstr "لا يمكن إنشاء المجلد." +msgstr "لا يمكن تØميل المجلد ÙÙŠ:" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error saving file!" -msgstr "خطأ ÙÙŠ ØÙظ مجموعة البلاط!" +msgstr "خطأ ÙÙŠ ØÙظ الملÙ!" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error while saving theme." -msgstr "خطأ خلال الØÙظ." +msgstr "خطأ أثناء ØÙظ الموضوع (Theme)." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error Saving" -msgstr "خطأ ÙÙŠ تØريك:" +msgstr "خطأ ÙÙŠ الØÙظ" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error importing theme." -msgstr "خطأ ÙÙŠ تØريك:" +msgstr "خطأ ÙÙŠ استيراد الموضوع (Theme)." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error Importing" -msgstr "خطأ ÙÙŠ تØريك:" +msgstr "خطأ ÙÙŠ الاستيراد" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New Text File..." -msgstr "مجلد جديد..." +msgstr "مل٠نصي جديد..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open File" -msgstr "Ø¥ÙØªØ Ù…Ù„Ù" +msgstr "اÙØªØ Ø§Ù„Ù…Ù„Ù" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Save File As..." -msgstr "ØÙظ باسم..." +msgstr "ØÙظ المل٠ك..." #: editor/plugins/script_editor_plugin.cpp msgid "Can't obtain the script for running." -msgstr "" +msgstr "لا يمكن الØصول على النص البرمجي للتشغيل." #: editor/plugins/script_editor_plugin.cpp msgid "Script failed reloading, check console for errors." -msgstr "" +msgstr "أخÙÙ‚ تØميل النص البرمجي، تÙقد الأخطاء ÙÙŠ العارض console." #: editor/plugins/script_editor_plugin.cpp msgid "Script is not in tool mode, will not be able to run." -msgstr "" +msgstr "النص البرمجي ليس ÙÙŠ وضعية الأداة، لم ÙŠÙ†Ø¬Ø Ø§Ù„ØªØ´ØºÙŠÙ„." #: editor/plugins/script_editor_plugin.cpp msgid "" "To run this script, it must inherit EditorScript and be set to tool mode." msgstr "" +"ليتم تشغيل النص البرمجي، ينبغي أن يرث النص البرمجي للمØرر EditorScript وأن " +"ÙŠÙضع ÙÙŠ وضعية الأداة." #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" -msgstr "" +msgstr "استيراد الموضوع Theme" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" -msgstr "" +msgstr "خطأ أثناء ØÙظ الموضوع Theme" #: editor/plugins/script_editor_plugin.cpp msgid "Error saving" @@ -6938,36 +6856,33 @@ msgstr "خطأ ÙÙŠ الØÙظ" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As..." -msgstr "" +msgstr "ØÙظ الموضوع Theme Ùƒ..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "%s Class Reference" -msgstr " مرجع الصنÙ" +msgstr "%s مرجعية الص٠Class" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Next" -msgstr "بØØ« عن التالي" +msgstr "ابØØ« عن التالي" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Previous" -msgstr "" +msgstr "إيجاد السابق" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Filter scripts" -msgstr "خصائص العنصر." +msgstr "ØªØ´Ø±ÙŠØ Ø§Ù„Ù†ØµÙˆØµ البرمجية" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." -msgstr "" +msgstr "تÙعيل الترتيب الألÙبائي لقائمة الدوال." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Filter methods" -msgstr "وضع المÙصÙÙŠ:" +msgstr "ØªØ±Ø´ÙŠØ Ø§Ù„Ø¯ÙˆØ§Ù„" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" @@ -6987,25 +6902,23 @@ msgstr "تØرك لأسÙÙ„" #: editor/plugins/script_editor_plugin.cpp msgid "Next script" -msgstr "" +msgstr "النص البرمجي التالي" #: editor/plugins/script_editor_plugin.cpp msgid "Previous script" -msgstr "" +msgstr "النص البرمجي السابق" #: editor/plugins/script_editor_plugin.cpp msgid "File" msgstr "ملÙ" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open..." -msgstr "Ø¥ÙتØ" +msgstr "اÙتØ..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Reopen Closed Script" -msgstr "ÙØªØ Ø§Ù„ÙƒÙˆØ¯" +msgstr "إعادة ÙØªØ Ø§Ù„Ù†Øµ البرمجي المÙغلق" #: editor/plugins/script_editor_plugin.cpp msgid "Save All" @@ -7013,117 +6926,115 @@ msgstr "اØÙظ الكل" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" -msgstr "" +msgstr "إعادة تØميل النص البرمجي بلطÙ" #: editor/plugins/script_editor_plugin.cpp msgid "Copy Script Path" -msgstr "نسخ مسار الكود" +msgstr "نسخ مسار النص البرمجي" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "History Previous" -msgstr "التبويب السابق" +msgstr "التأريخ السابق" #: editor/plugins/script_editor_plugin.cpp msgid "History Next" -msgstr "" +msgstr "التأريخ التالي" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Theme" -msgstr "" +msgstr "الموضوع" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Import Theme..." -msgstr "Øاري إستيراد المشهد..." +msgstr "استيراد الموضوع…" #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" -msgstr "" +msgstr "إعادة تØميل الموضوع" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme" -msgstr "" +msgstr "اØÙظ الموضوع" #: editor/plugins/script_editor_plugin.cpp msgid "Close All" -msgstr "" +msgstr "إغلاق الكل" #: editor/plugins/script_editor_plugin.cpp msgid "Close Docs" -msgstr "" +msgstr "إغلاق المستندات" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "" +msgstr "تشغيل" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "" +msgstr "خطوة ضمن" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" -msgstr "" +msgstr "خطوة متجاوزة" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" -msgstr "" +msgstr "توقÙ" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp msgid "Continue" -msgstr "" +msgstr "استمرار" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" -msgstr "" +msgstr "إبقاء منÙÙ‚ØªØ Ø§Ù„Ø£Ø®Ø·Ø§Ø¡ البرمجية Ù…ÙتوØاً" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Debug with External Editor" -msgstr "ÙØªØ ÙÙŠ المÙعدل التالي" +msgstr "ØªÙ†Ù‚ÙŠØ Ø§Ù„Ø£Ø®Ø·Ø§Ø¡ ÙÙŠ Ù…Øرر خارجي" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "ÙÙØªØ Ù…Ø¤Ø®Ø±Ø§Ù‹" +msgstr "اÙØªØ Ù…Ø³ØªÙ†Ø¯Ø§Øª غودوت على الشبكة." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." -msgstr "" +msgstr "ابØØ« ÙÙŠ الوثائق المرجعية." #: editor/plugins/script_editor_plugin.cpp msgid "Go to previous edited document." -msgstr "" +msgstr "التوجه إلى المستند المÙØرر السابق." #: editor/plugins/script_editor_plugin.cpp msgid "Go to next edited document." -msgstr "" +msgstr "التوجه إلى المستند المÙØرر التالي." #: editor/plugins/script_editor_plugin.cpp msgid "Discard" -msgstr "" +msgstr "تجاهل" #: editor/plugins/script_editor_plugin.cpp msgid "" "The following files are newer on disk.\n" "What action should be taken?:" msgstr "" +"الملÙات التالية Ø£Øدث على القرص.\n" +"ما الإجراء الذي ينبغي اتخاذه؟:" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Reload" -msgstr "" +msgstr "إعادة تØميل" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Resave" -msgstr "" +msgstr "إعادة ØÙظ" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "" +msgstr "Ù…ÙÙ†Ù‚Ø Ø§Ù„Ø£Ø®Ø·Ø§Ø¡" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7147,7 +7058,7 @@ msgstr "مورد" #: editor/plugins/script_text_editor.cpp msgid "Target" -msgstr "" +msgstr "الهدÙ" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7162,7 +7073,7 @@ msgstr "الخط:" #: editor/plugins/script_text_editor.cpp msgid "(ignore)" -msgstr "" +msgstr "(تجاهل)" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7171,50 +7082,50 @@ msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ù‡Ù…Ø©" #: editor/plugins/script_text_editor.cpp msgid "Only resources from filesystem can be dropped." -msgstr "" +msgstr "يمكن إسقاط موارد ملÙات النظام filesystem Ùقط." #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Can't drop nodes because script '%s' is not used in this scene." -msgstr "" +msgstr "لا يمكن إسقاط العÙقد لأن النص البرمجي '%s' غير Ù…Ùستخدم ÙÙŠ هذا المشهد." #: editor/plugins/script_text_editor.cpp msgid "Lookup Symbol" -msgstr "" +msgstr "رمز البØØ«" #: editor/plugins/script_text_editor.cpp msgid "Pick Color" -msgstr "" +msgstr "اختر لوناً" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Convert Case" -msgstr "" +msgstr "Øالة التØويل" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Uppercase" -msgstr "" +msgstr "الأØر٠الكبيرة (Uppercase)" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Lowercase" -msgstr "" +msgstr "الأØر٠الصغيرة (Lowercase)" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Capitalize" -msgstr "" +msgstr "تكبير الØرو٠Capitalize" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" -msgstr "" +msgstr "Ù…Ùعلّم التركيب Syntax" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Go To" -msgstr "" +msgstr "التوجه إلى" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "المØÙوظات" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7224,7 +7135,7 @@ msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø§Ø·" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" -msgstr "" +msgstr "قص" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp @@ -7233,19 +7144,19 @@ msgstr "تØديد الكل" #: editor/plugins/script_text_editor.cpp msgid "Delete Line" -msgstr "" +msgstr "Øذ٠الخط" #: editor/plugins/script_text_editor.cpp msgid "Indent Left" -msgstr "" +msgstr "المساÙØ© البادئة يساراً" #: editor/plugins/script_text_editor.cpp msgid "Indent Right" -msgstr "" +msgstr "المساÙØ© البادئة يميناً" #: editor/plugins/script_text_editor.cpp msgid "Toggle Comment" -msgstr "" +msgstr "تÙعيل Toggle التعليقات" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -7253,19 +7164,19 @@ msgstr "إلغاء/تÙعيل طي الخط" #: editor/plugins/script_text_editor.cpp msgid "Fold All Lines" -msgstr "" +msgstr "طي جميع الخطوط" #: editor/plugins/script_text_editor.cpp msgid "Unfold All Lines" -msgstr "" +msgstr "كش٠جميع الخطوط" #: editor/plugins/script_text_editor.cpp msgid "Clone Down" -msgstr "" +msgstr "استنساخ أدناه" #: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" -msgstr "" +msgstr "رمز التمام" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7274,7 +7185,7 @@ msgstr "تكبير المØدد" #: editor/plugins/script_text_editor.cpp msgid "Trim Trailing Whitespace" -msgstr "" +msgstr "تشذيب الÙراغات البيضاء الزائدة" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7288,7 +7199,7 @@ msgstr "تØويل إلي %s" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" -msgstr "" +msgstr "مساÙØ© بادئة تلقائية" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7297,7 +7208,7 @@ msgstr "Ùلتر الملÙات..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" -msgstr "" +msgstr "مساعدة سياقية" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7332,11 +7243,11 @@ msgstr "إذهب إلي الخط" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "" +msgstr "تÙعيل/إلغاء تÙعيل نقطة التكسّر" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "" +msgstr "إزالة جميع نقاط التكسّر" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7353,14 +7264,16 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" +"لقد تم تعديل هذا المÙظلل على القرص.\n" +"ما الإجراء الذي ينبغي اتخاذه؟" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "" +msgstr "Ù…Ùظلل" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "This skeleton has no bones, create some children Bone2D nodes." -msgstr "" +msgstr "لا يملك هذا الهكيل أيّة عظام، أنشئ بعض عÙقد العظام ثنائية البÙعد كأبناء." #: editor/plugins/skeleton_2d_editor_plugin.cpp #, fuzzy @@ -7369,20 +7282,19 @@ msgstr "أنشئ نقاط إنبعاث من الشبكة" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Rest Pose to Bones" -msgstr "" +msgstr "تØديد وضعية الراØØ© على العظام" #: editor/plugins/skeleton_2d_editor_plugin.cpp -#, fuzzy msgid "Skeleton2D" -msgstr "الÙردية" +msgstr "هيكل ثنائي البÙعد" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Make Rest Pose (From Bones)" -msgstr "" +msgstr "إنشاء وضعية الراØØ© (من العظام)" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Bones to Rest Pose" -msgstr "" +msgstr "تØديد العظام لتكون ÙÙŠ وضعية الراØØ©" #: editor/plugins/skeleton_editor_plugin.cpp #, fuzzy @@ -7405,35 +7317,35 @@ msgstr "تشغيل" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" -msgstr "" +msgstr "متعامد" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective" -msgstr "" +msgstr "منظوري" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Aborted." -msgstr "" +msgstr "أجهض التØول." #: editor/plugins/spatial_editor_plugin.cpp msgid "X-Axis Transform." -msgstr "" +msgstr "التØوّل المØوري X." #: editor/plugins/spatial_editor_plugin.cpp msgid "Y-Axis Transform." -msgstr "" +msgstr "التØوّل المØوري Y." #: editor/plugins/spatial_editor_plugin.cpp msgid "Z-Axis Transform." -msgstr "" +msgstr "التØوّل المØوري Z." #: editor/plugins/spatial_editor_plugin.cpp msgid "View Plane Transform." -msgstr "" +msgstr "إظهار تØولات المستوى." #: editor/plugins/spatial_editor_plugin.cpp msgid "Scaling: " -msgstr "" +msgstr "ÙŠÙØجم: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Translating: " @@ -7441,103 +7353,103 @@ msgstr "يترجم: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." -msgstr "" +msgstr "ÙŠÙدير %s من الدرجات." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." -msgstr "" +msgstr "تم تعطيل تعيين المÙØ§ØªÙŠØ (لم يتم إدخال أيّة Ù…ÙاتيØ)." #: editor/plugins/spatial_editor_plugin.cpp msgid "Animation Key Inserted." -msgstr "" +msgstr "Ø£Ùدخل Ù…ÙØªØ§Ø Ø§Ù„Ø±Ø³ÙˆÙ… المتØركة." #: editor/plugins/spatial_editor_plugin.cpp msgid "Pitch" -msgstr "" +msgstr "Øدّة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Yaw" -msgstr "" +msgstr "الإنØرا٠Yaw" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" -msgstr "" +msgstr "كائنات مرسومة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Material Changes" -msgstr "" +msgstr "تÙغيرات المادة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Shader Changes" -msgstr "" +msgstr "تغيرات المÙظلل" #: editor/plugins/spatial_editor_plugin.cpp msgid "Surface Changes" -msgstr "" +msgstr "تغيرات السطØ" #: editor/plugins/spatial_editor_plugin.cpp msgid "Draw Calls" -msgstr "" +msgstr "رسم الاستدعاءات" #: editor/plugins/spatial_editor_plugin.cpp msgid "Vertices" -msgstr "" +msgstr "القمم" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." -msgstr "" +msgstr "الواجهة العلوية." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View." -msgstr "" +msgstr "الواجهة السÙلية." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom" -msgstr "" +msgstr "الأسÙÙ„" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View." -msgstr "" +msgstr "الواجهة اليÙسرى." #: editor/plugins/spatial_editor_plugin.cpp msgid "Left" -msgstr "" +msgstr "اليسار" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View." -msgstr "" +msgstr "الواجهة اليÙمنى." #: editor/plugins/spatial_editor_plugin.cpp msgid "Right" -msgstr "" +msgstr "اليمين" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View." -msgstr "" +msgstr "الواجهة الأمامية." #: editor/plugins/spatial_editor_plugin.cpp msgid "Front" -msgstr "" +msgstr "الأمام" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View." -msgstr "" +msgstr "الواجهة الخلÙية." #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear" -msgstr "" +msgstr "الخلÙ" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align Transform with View" -msgstr "" +msgstr "Ù…Øاذاة التØوّل مع الواجهة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align Rotation with View" -msgstr "" +msgstr "Ù…Øاذاة التدوير مع الواجهة" #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "No parent to instance a child at." -msgstr "لا أب للصق الطÙÙ„ عليه." +msgstr "لا أب لنمذجة ابن له." #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "This operation requires a single selected node." @@ -7545,19 +7457,19 @@ msgstr "هذه العملية تتطلب عقدة واØدة Ù…Øددة." #: editor/plugins/spatial_editor_plugin.cpp msgid "Auto Orthogonal Enabled" -msgstr "" +msgstr "الإسقاط العمودي Ù…Ùمكن تلقائياً" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" -msgstr "" +msgstr "Ù‚ÙÙ„ تدوير الواجهة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" -msgstr "" +msgstr "عرض الطبيعي" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Wireframe" -msgstr "" +msgstr "عرض المÙخطط Wireframe" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Overdraw" @@ -7565,31 +7477,31 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Unshaded" -msgstr "" +msgstr "عرض من غير ظلال" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Environment" -msgstr "" +msgstr "عرض البيئة" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Gizmos" -msgstr "" +msgstr "إظهار الأدوات Gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Information" -msgstr "" +msgstr "إظهار المعلومات" #: editor/plugins/spatial_editor_plugin.cpp msgid "View FPS" -msgstr "إظهار الÙريم/ثانية" +msgstr "إظهار عدد الإطارات بالثانية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Half Resolution" -msgstr "نص٠Øجم الشاشة" +msgstr "نص٠دقة الشاشة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Audio Listener" -msgstr "" +msgstr "المستمع الصوتي" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy @@ -7603,62 +7515,63 @@ msgstr "ÙŠÙنشئ مستعرضات الميش" #: editor/plugins/spatial_editor_plugin.cpp msgid "Not available when using the GLES2 renderer." -msgstr "" +msgstr "غير متواÙر عند استخدام الخرج البصري GLES2 ." #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" -msgstr "" +msgstr "الرؤية الØÙرة Freelook يساراً" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Right" -msgstr "" +msgstr "الرؤية الØرة Freelook يميناً" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Forward" -msgstr "" +msgstr "الرؤية الØرة Freelook Ù‚Ùدماً" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Backwards" -msgstr "" +msgstr "الرؤية الØÙرة Freelook تراجعياً" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Up" -msgstr "" +msgstr "الرؤية الØÙرة Freelook للأعلى" #: 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 "View Rotation Locked" -msgstr "" +msgstr "تدوير الرؤية مقÙول" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" +"ملاØظة: إن قيمة عدد الإطارات بالثانية الظاهر هو Ù…Ùعدل خاص بالمØرر.\n" +"لا يمكن الاعتماد على تلك القيمة كمؤشر لأداء اللعبة." #: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" -msgstr "" +msgstr "ناÙذة XForm" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Nodes To Floor" -msgstr "الكبس إلي الشبكة" +msgstr "Ù…Øاذاة العÙقد إلى الأرضية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Couldn't find a solid floor to snap the selection to." -msgstr "" +msgstr "لم يتم إيجاد أرضية صÙلبة لمØاذاة ما تم اختياره إليها." #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -7666,63 +7579,66 @@ msgid "" "Alt+Drag: Move\n" "Alt+RMB: Depth list selection" msgstr "" +"السØب: تدوير.\n" +"Alt+السØب: تØريك.\n" +"Alt+ كبسة الزر الأيمن للÙأرةRMB : اختيار قائمة العÙمق" #: editor/plugins/spatial_editor_plugin.cpp msgid "Use Local Space" -msgstr "" +msgstr "استخدام الØيّز المØلي" #: editor/plugins/spatial_editor_plugin.cpp msgid "Use Snap" -msgstr "إستخدم الكبس" +msgstr "استخدام المØاذاة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" -msgstr "" +msgstr "الواجهة View السÙلية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View" -msgstr "" +msgstr "الواجهة View العلوية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View" -msgstr "" +msgstr "الواجهة View الخلÙية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View" -msgstr "" +msgstr "الواجهة View الأمامية" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View" -msgstr "" +msgstr "الواجهة View اليÙسرى" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View" -msgstr "" +msgstr "الواجهة View اليÙمنى" #: editor/plugins/spatial_editor_plugin.cpp msgid "Switch Perspective/Orthogonal View" -msgstr "" +msgstr "التبديل بين الرؤية المنظورية / الإسقاطية Orthogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" -msgstr "" +msgstr "إدخال Ù…ÙØªØ§Ø Ù„Ù„Ø±Ø³ÙˆÙ…ÙŠØ§Øª المتØركة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Origin" -msgstr "" +msgstr "مصدر التركيز" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Selection" -msgstr "" +msgstr "اختيار التركيز" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Freelook" -msgstr "إلغاء/تÙعيل وضع النظرة الØرة" +msgstr "إلغاء/تÙعيل وضع الرؤية الØÙرة" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Transform" -msgstr "" +msgstr "التØوّل" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy @@ -7731,43 +7647,43 @@ msgstr "الكبس إلي الشبكة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." -msgstr "" +msgstr "ناÙذة التØويلات ..." #: editor/plugins/spatial_editor_plugin.cpp msgid "1 Viewport" -msgstr "" +msgstr "إطار عرض واØد 1" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports" -msgstr "" +msgstr "إطاري عرض" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports (Alt)" -msgstr "" +msgstr "إطاري عرض (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports" -msgstr "" +msgstr "3 إطارات عرض" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports (Alt)" -msgstr "" +msgstr "3 إطارات عرض (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "4 Viewports" -msgstr "" +msgstr "4 إطارات عرض" #: editor/plugins/spatial_editor_plugin.cpp msgid "Gizmos" -msgstr "" +msgstr "الأدوات Gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Origin" -msgstr "" +msgstr "إظهار الأصل (المصدر)" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Grid" -msgstr "" +msgstr "إظهار الشبكة" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7777,67 +7693,68 @@ msgstr "جاري الإعداد..." #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" -msgstr "" +msgstr "إعدادات المØاذاة" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate Snap:" -msgstr "" +msgstr "ترجمة المØاذاة:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Snap (deg.):" -msgstr "" +msgstr "تدوير المØاذاة (بالدرجات):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Snap (%):" -msgstr "" +msgstr "تØجيم المØاذاة (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" -msgstr "" +msgstr "إعدادات إطار العرض" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" -msgstr "" +msgstr "مجال الرؤية FOV المنظورية (بالدرجات):" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Z-Near:" -msgstr "" +msgstr "إظهار Z-Near:" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "View Z-Far:" -msgstr "" +msgstr "إظهار Z-Far:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Change" -msgstr "" +msgstr "تعديل التØولات" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate:" -msgstr "" +msgstr "الترجمة:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate (deg.):" -msgstr "" +msgstr "التدوير (بالدرجات):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale (ratio):" -msgstr "" +msgstr "التØجيم (نسبةً):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Type" -msgstr "" +msgstr "نوع التØوّل" #: editor/plugins/spatial_editor_plugin.cpp msgid "Pre" -msgstr "" +msgstr "سابق" #: editor/plugins/spatial_editor_plugin.cpp msgid "Post" -msgstr "" +msgstr "لاØÙ‚" #: editor/plugins/spatial_editor_plugin.cpp msgid "Nameless gizmo" -msgstr "" +msgstr "أداة (gizmo) غير مسماة" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7856,7 +7773,7 @@ msgstr "إنشاء بولي" #: editor/plugins/sprite_editor_plugin.cpp msgid "Polygon2D Preview" -msgstr "" +msgstr "Ù…Ùعاينة المÙضلع ثنائي الأبعاد" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7886,10 +7803,12 @@ msgstr "الميش Ùارغ!" #: editor/plugins/sprite_editor_plugin.cpp msgid "Can't convert a sprite using animation frames to mesh." msgstr "" +"لا يمكن تØويل الرسومية (sprite) إلى Ø³Ø·Ø (mesh) باستخدام إطارات الرسوم " +"المتØركة." #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "هندسياً غير صالØØŒ لا يمكن استبداله Ø¨Ø³Ø·Ø (mesh)." #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7898,7 +7817,7 @@ msgstr "تØويل إلي %s" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." -msgstr "" +msgstr "هندسياصً غير صالØØŒ لا يمكن إنشاء Ù…Ùضلّع." #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7907,7 +7826,7 @@ msgstr "تØويل إلي %s" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "" +msgstr "هندسياً غير صالØØŒ لا يمكن إنشاء Ù…Ùضلع تصادم." #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7916,7 +7835,7 @@ msgstr "إنشاء Ù…Ùضلع التنقل" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." -msgstr "" +msgstr "هندسياً غير صالØØŒ لا يمكن إنشاء ØÙظار (occluder) الضوء." #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7925,19 +7844,19 @@ msgstr "أنشئ شكل Ù…Ùطبق" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" -msgstr "" +msgstr "رسومية" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "التبسيط: " #: editor/plugins/sprite_editor_plugin.cpp msgid "Shrink (Pixels): " -msgstr "" +msgstr "التقلص (Pixels): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Grow (Pixels): " -msgstr "" +msgstr "التكبير (Pixels): " #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7945,79 +7864,72 @@ msgid "Update Preview" msgstr "إستعراض" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Settings:" -msgstr "إعدادات المÙعدل" +msgstr "الإعدادات:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "إملئ الشاشة بالمØدد" +msgstr "لا إطارات Ù…ÙØددة" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add %d Frame(s)" -msgstr "" +msgstr "إضاÙØ© %d إطار(ات)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" -msgstr "" +msgstr "إضاÙØ© إطار" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Unable to load images" -msgstr "Ùشل تØميل المورد." +msgstr "غير قادر على تØميل الصور" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "" +msgstr "خطأ: لم يتم تØميل مورد الإطار!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" -msgstr "" +msgstr "إما أن تكون ØاÙظة الموارد Ùارغة أو ليست نقشاً!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Paste Frame" -msgstr "" +msgstr "الصق إطاراً" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Empty" -msgstr "" +msgstr "إضاÙته Ùارغاً" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation FPS" -msgstr "" +msgstr "تغيير Ù…Ùعدل الإطارات ÙÙŠ الثانية FPS للرسوم المتØركة" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "(empty)" -msgstr "" +msgstr "(Ùارغ)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Move Frame" -msgstr "وضع التØريك" +msgstr "تØريك الإطار" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animations:" -msgstr "صورة متØركة" +msgstr "الرسومات المتØركة:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "New Animation" -msgstr "صورة متØركة" +msgstr "رسومية متØركة جديدة" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed (FPS):" -msgstr "" +msgstr "السرعة (إطار Ù. Ø«. FPS):" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Loop" -msgstr "" +msgstr "Øلقة Loop" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animation Frames:" -msgstr "إسم الØركة:" +msgstr "إطارات الرسومات المتØركة:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -8026,15 +7938,15 @@ msgstr "التقط من البيكسل" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "إضاÙØ© الإطارات من ورقة الرسوميات Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" -msgstr "" +msgstr "إضاÙته Ùارغاً (قبل)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (After)" -msgstr "" +msgstr "إضاÙته Ùارغاً (بَعد)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move (Before)" @@ -8051,61 +7963,60 @@ msgstr "تØديد الوضع" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Horizontal:" -msgstr "" +msgstr "عَرضياً:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Vertical:" -msgstr "" +msgstr "شاقولياً:" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Select/Clear All Frames" -msgstr "" +msgstr "اختيار / Ù…Ø³Ø Ø¬Ù…ÙŠØ¹ الإطارات" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Create Frames from Sprite Sheet" -msgstr "" +msgstr "إنشاء الإطارات من ورقة الرسومية Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" -msgstr "" +msgstr "إطارات الرسوميات SpriteFrames" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Region Rect" -msgstr "" +msgstr "تØديد مستطيل المنطقة" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "Set Margin" -msgstr "Øدد المعامل" +msgstr "تØديد الهامش" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" -msgstr "" +msgstr "وضع المØاذاة:" #: editor/plugins/texture_region_editor_plugin.cpp #: scene/resources/visual_shader.cpp msgid "None" -msgstr "" +msgstr "لا شيء" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" -msgstr "" +msgstr "Ù…Øاذاة البكسل" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "" +msgstr "شبكة المØاذاة" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" -msgstr "" +msgstr "الاقتطاع التلقائي" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Offset:" -msgstr "" +msgstr "المÙعادل:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Step:" -msgstr "" +msgstr "الخطوة:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Sep.:" @@ -8113,32 +8024,31 @@ msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp msgid "TextureRegion" -msgstr "" +msgstr "منطقة النقش TextureRegion" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All Items" -msgstr "" +msgstr "إضاÙØ© جميع العناصر" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All" -msgstr "" +msgstr "إضاÙØ© الجميع" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove All Items" -msgstr "" +msgstr "إزالة جميع العناصر" #: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp msgid "Remove All" msgstr "Ù…Ø³Ø Ø§Ù„ÙƒÙ„" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "الأعضاء" +msgstr "تØرير الموضوع" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." -msgstr "" +msgstr "قائمة تØرير الموضوع." #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" @@ -8150,15 +8060,15 @@ msgstr "Øذ٠بنود من الصنÙ" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Template" -msgstr "" +msgstr "إنشاء قالب Ùارغ" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Editor Template" -msgstr "" +msgstr "إنشاء قالب Ù…ÙØرر Ùارغ" #: editor/plugins/theme_editor_plugin.cpp msgid "Create From Current Editor Theme" -msgstr "" +msgstr "إنشاء مستمد من موضوع Theme المØرر الØالي" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -8201,7 +8111,7 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "القائمة الÙرعية" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -8215,11 +8125,11 @@ msgstr "عنصر" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" -msgstr "" +msgstr "يملك" #: editor/plugins/theme_editor_plugin.cpp msgid "Many" -msgstr "" +msgstr "العديد" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -8245,7 +8155,7 @@ msgstr "عنصر انتقاء" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "الشجرة الÙرعية" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -8254,24 +8164,24 @@ msgstr "بكثير، خيارات عديدة،!" #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" -msgstr "" +msgstr "نوع البيانات:" #: editor/plugins/theme_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp msgid "Icon" -msgstr "" +msgstr "الأيقونة" #: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp msgid "Style" -msgstr "" +msgstr "الأسلوب" #: editor/plugins/theme_editor_plugin.cpp msgid "Font" -msgstr "" +msgstr "الخط" #: editor/plugins/theme_editor_plugin.cpp msgid "Color" -msgstr "" +msgstr "اللون" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -8280,7 +8190,7 @@ msgstr "Ø¥ÙØªØ Ù…Ù„Ù" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase Selection" -msgstr "" +msgstr "إزالة عملية الاختيار" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8295,23 +8205,23 @@ msgstr "نص٠المÙØدد" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" -msgstr "" +msgstr "طلاء خريطة البلاط TileMap" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Line Draw" -msgstr "" +msgstr "رسم الخط" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rectangle Paint" -msgstr "" +msgstr "مستطيل الطلاء" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" -msgstr "" +msgstr "وعاء التعبئة" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" -msgstr "" +msgstr "Ù…Ø³Ø Ø®Ø±ÙŠØ·Ø© البلاط TileMap" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8320,11 +8230,11 @@ msgstr "جد" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" -msgstr "" +msgstr "المصÙÙˆÙØ© المنقولة Transpose" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Disable Autotile" -msgstr "" +msgstr "تعطيل البلاط التلقائي Autotile" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8339,20 +8249,23 @@ msgstr "Ùلتر الملÙات..." #: editor/plugins/tile_map_editor_plugin.cpp msgid "Give a TileSet resource to this TileMap to use its tiles." msgstr "" +"Ù…Ù†Ø Ù…ÙˆØ±Ø¯ Ù…ÙØدد البلاطات TileSet لخريطة البلاط TileMap هذه كي تستخدم بلاطاتها." #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" -msgstr "" +msgstr "طلاء البلاط" #: editor/plugins/tile_map_editor_plugin.cpp msgid "" "Shift+LMB: Line Draw\n" "Shift+Ctrl+LMB: Rectangle Paint" msgstr "" +"Shift+ الزر الأيسر للÙأرة: الرسم خطياً\n" +"Shift+Ctrl+الزر الأيسر للÙأرة: طلاء المستطيلات" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" -msgstr "" +msgstr "اختيار البلاط" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8366,11 +8279,11 @@ msgstr "وضع التدوير" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Horizontally" -msgstr "" +msgstr "القلب Ø£Ùقياً" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Vertically" -msgstr "" +msgstr "القلب شاقولياً" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8379,7 +8292,7 @@ msgstr "تØويل تغيير التØريك" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." -msgstr "" +msgstr "إضاÙØ© نقش(نقوش) إلى Ù…ÙØدد البلاط TileSet." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8388,15 +8301,15 @@ msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø¯Ø®Ù„Ø© الØالية" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" -msgstr "" +msgstr "إنشاء من المشهد" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from Scene" -msgstr "" +msgstr "دمج من المشهد" #: editor/plugins/tile_set_editor_plugin.cpp msgid "New Single Tile" -msgstr "" +msgstr "بلاطة Ù…ÙÙردة جديدة" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8405,15 +8318,15 @@ msgstr "إظهار الملÙات" #: editor/plugins/tile_set_editor_plugin.cpp msgid "New Atlas" -msgstr "" +msgstr "أطلس جديد" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Next Coordinate" -msgstr "" +msgstr "الإØداثات التالية" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the next shape, subtile, or Tile." -msgstr "" +msgstr "اختر الشكل أو البلاط الÙرعي أو البلاط التالي." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8422,86 +8335,71 @@ msgstr "التبويب السابق" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the previous shape, subtile, or Tile." -msgstr "" +msgstr "اختر الشكل أو البلاط الÙرعي أو البلاط، السابق." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region" -msgstr "وضع التدوير" +msgstr "الإقليم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision" -msgstr "وضعية الأستيÙاء" +msgstr "التصادم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion" -msgstr "تعديل البولي" +msgstr "الإطباق Occlusion" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation" -msgstr "أنشئ ميش التنقل" +msgstr "التصÙØ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask" -msgstr "وضع التدوير" +msgstr "قناع البÙت Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority" -msgstr "تصدير المشروع" +msgstr "التÙاضل Priority" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index" -msgstr "وضع السØب" +msgstr "تراتبية المØور Z" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "وضع التدوير" +msgstr "وضع الأقليم Region" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "وضعية الأستيÙاء" +msgstr "وضع التصادم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "تعديل البولي" +msgstr "وضع الإطباق Occlusion" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "أنشئ ميش التنقل" +msgstr "وضع التصÙØ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "وضع التدوير" +msgstr "وضع Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "تصدير المشروع" +msgstr "وضع التÙاضل Priority" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "وضع السØب" +msgstr "وضع الأيقونة" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "وضع السØب" +msgstr "وضع Z Index" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." -msgstr "" +msgstr "نسخ bitmask." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8519,84 +8417,86 @@ msgid "Create a new rectangle." msgstr "إنشاء %s جديد" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create a new polygon." -msgstr "أنشئ شكل جديد من لا شئ." +msgstr "إنشاء Ù…Ùضلع جديد." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." -msgstr "" +msgstr "إبقاء المÙضلع داخل مستطيل المنطقة." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." -msgstr "" +msgstr "تمكين المØاذاة وإظهار الشبكة (التهيئة عبر المÙتÙØص)." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Display Tile Names (Hold Alt Key)" -msgstr "" +msgstr "تعطيل أسماء البلاطات (اضغط على زر Alt)" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Add or select a texture on the left panel to edit the tiles bound to it." -msgstr "" +msgstr "أض٠أو اختر نقشاً من اللوØØ© على اليسار لتØرير البلاطات المقترنة بها." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected texture? This will remove all tiles which use it." -msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø¯Ø®Ù„Ø© الØالية" +msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø´ المÙختار؟ هذا سيزيل جميع البلاطات التي تستخدمه." #: editor/plugins/tile_set_editor_plugin.cpp msgid "You haven't selected a texture to remove." -msgstr "" +msgstr "لم تختر نقشاً لإزالته." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from scene? This will overwrite all current tiles." msgstr "" +"إنشاء اعتماداً على مشهد؟ هذا سيكتب متجاوزاً overwrite جميع البلاطات الØالية." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" -msgstr "" +msgstr "دمج من مشهد؟" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Texture" -msgstr "Ù…Ø³Ø Ø§Ù„Ù‚Ø§Ù„Ø¨" +msgstr "إزالة النقش" #: editor/plugins/tile_set_editor_plugin.cpp msgid "%s file(s) were not added because was already on the list." -msgstr "" +msgstr "%s الملÙ(ات) لم تض٠بسبب كونها موجودة سلÙاً بالقائمة." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Drag handles to edit Rect.\n" "Click on another Tile to edit it." msgstr "" +"اسØب المقابض لتØرير المستطيل.\n" +"اضغط على بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete selected Rect." -msgstr "Ø¥Ù…Ø³Ø Ø§Ù„Ù…Ù„Ùات المØددة؟" +msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø³ØªØ·ÙŠÙ„Ø§Øª المØددة." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select current edited sub-tile.\n" "Click on another Tile to edit it." -msgstr "ØÙظ العنوان الÙرعي الذي يتم تعديله Øاليا." +msgstr "" +"اختر البلاطات الÙرعية المÙØددة Øديثاً.\n" +"اضغط على بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete polygon." -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø§Ø·" +msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ùضلع." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" "Shift+LMB: Set wildcard bit.\n" "Click on another Tile to edit it." -msgstr "ØÙظ العنوان الÙرعي الذي يتم تعديله Øاليا." +msgstr "" +"الزر الأيسر للÙأرة: تشغيل bit.\n" +"الزر الأيمن للÙأرة: إطÙاء bit.\n" +"Shift+الزر الأيسر للÙأرة: تØديد wildcard bit.\n" +"اضغط على بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -8604,210 +8504,189 @@ msgid "" "bindings.\n" "Click on another Tile to edit it." msgstr "" +"اختر بلاطة Ùرعية لاستخدامها كأيقونة، Øيث سيتم استخدامها ÙÙŠ قرن البلاط " +"التلقائي غير الصالØ.\n" +"اضغط على بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Select sub-tile to change its priority.\n" "Click on another Tile to edit it." msgstr "" +"اختر بلاطة Ùرعية لتغير التÙاضل الخاص بها.\n" +"اختر بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select sub-tile to change its z index.\n" "Click on another Tile to edit it." -msgstr "ØÙظ العنوان الÙرعي الذي يتم تعديله Øاليا." +msgstr "" +"اختر بلاطة Ùرعية لتغير ترتيبها على المØور Z.\n" +"اضغط على بلاطة أخرى لتØريرها." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Region" -msgstr "" +msgstr "تØديد منطقة البلاط" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Tile" -msgstr "أنشئ مجلد" +msgstr "إنشاء بلاط" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Icon" -msgstr "" +msgstr "تØديد أيقونة البلاط" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Bitmask" -msgstr "تعديل المصاÙÙŠ" +msgstr "تØرير قناع البÙت Bitmask البلاط" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Collision Polygon" -msgstr "تعديل الشكل الموجود بالÙعل:" +msgstr "تعديل Ù…Ùضلع التصادم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Occlusion Polygon" -msgstr "تعديل البولي" +msgstr "تØرير Ù…Ùضلع الإطباق" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Navigation Polygon" -msgstr "إنشاء Ù…Ùضلع التنقل" +msgstr "تØرير Ù…Ùضلع التصÙØ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Paste Tile Bitmask" -msgstr "لصق الØركة" +msgstr "لصق قناع بÙت Bitmask البلاط" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Clear Tile Bitmask" -msgstr "" +msgstr "Ù…Ø³Ø Ù‚Ù†Ø§Ø¹ بÙت Bitmask البلاط" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Concave" -msgstr "" +msgstr "جعل المÙضلع Ù…Ùقعراً" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Polygon Convex" -msgstr "إنشاء بولي" +msgstr "جعل المÙضلع Ù…ÙØدّباً" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Tile" -msgstr "Ù…Ø³Ø Ø§Ù„Ù‚Ø§Ù„Ø¨" +msgstr "إزالة البلاط" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Collision Polygon" -msgstr "Ù…Ø³Ø Ø§Ù„Ø¨ÙˆÙ„ÙŠ والنقطة" +msgstr "إزالة Ù…Ùضلع التصادم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Occlusion Polygon" -msgstr "أنشئ شكل Ù…Ùطبق" +msgstr "إزالة Ù…Ùضلع الإطباق" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Navigation Polygon" -msgstr "إنشاء Ù…Ùضلع التنقل" +msgstr "إزالة Ù…Ùضلع التنقل" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Priority" -msgstr "تعديل المصاÙÙŠ" +msgstr "تعديل تÙاضل البلاط" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "" +msgstr "تعديل تراتبية البلاط على المØور Z" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Convex" -msgstr "إنشاء بولي" +msgstr "جعله Ù…ÙØدباً" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Concave" -msgstr "أنشئ عظام" +msgstr "جعله Ù…Ùقعراً" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Collision Polygon" -msgstr "إنشاء Ù…Ùضلع التنقل" +msgstr "إنشاء Ù…Ùضلع التصادم" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Occlusion Polygon" -msgstr "أنشئ شكل Ù…Ùطبق" +msgstr "إنشاء Ù…Ùضلع الإطباق Occlusion" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "This property can't be changed." -msgstr "هذه العملية لا يمكن الإكتمال من غير مشهد." +msgstr "لا يمكن تعديل هذه الخاصية." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "TileSet" -msgstr "مجموعة البلاط" +msgstr "Ù…ÙØدد البلاط" #: editor/plugins/version_control_editor_plugin.cpp msgid "No VCS addons are available." -msgstr "" +msgstr "لا يوجد إضاÙات VCS متواÙرة." #: editor/plugins/version_control_editor_plugin.cpp msgid "Error" -msgstr "" +msgstr "خطأ" #: 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 "No files added to stage" -msgstr "" +msgstr "لم يتم إضاÙØ© ملÙات إلى المرØلة" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Commit" -msgstr "المجتمع" +msgstr "ارتكاب" #: editor/plugins/version_control_editor_plugin.cpp msgid "VCS Addon is not initialized" -msgstr "" +msgstr "لم يتم تهيئة إضاÙات VCS" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" -msgstr "" +msgstr "نظام التØكم بالإصدار VCS" #: editor/plugins/version_control_editor_plugin.cpp msgid "Initialize" -msgstr "" +msgstr "الشروع" #: editor/plugins/version_control_editor_plugin.cpp msgid "Staging area" -msgstr "" +msgstr "Øيز التدريج" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Detect new changes" -msgstr "إنشاء %s جديد" +msgstr "الكش٠عن التغيرات الجديدة" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Changes" -msgstr "تغير" +msgstr "التغيرات" #: editor/plugins/version_control_editor_plugin.cpp msgid "Modified" -msgstr "" +msgstr "Ù…Ùعدّل" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Renamed" -msgstr "إعادة التسمية" +msgstr "Ù…Ùعاد تسميته" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Deleted" -msgstr "مسØ" +msgstr "Ù…Ùزال" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Typechange" -msgstr "تغير" +msgstr "تعديل النوع" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Stage Selected" -msgstr "تكبير المØدد" +msgstr "ØÙددت المرØلة" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Stage All" -msgstr "اØÙظ الكل" +msgstr "Ù…Ùجمل المراØÙ„" #: editor/plugins/version_control_editor_plugin.cpp msgid "Add a commit message" -msgstr "" +msgstr "إضاÙØ© رسالة إجراء" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -8817,11 +8696,11 @@ msgstr "مزامنة تغييرات الكود" #: editor/plugins/version_control_editor_plugin.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Status" -msgstr "" +msgstr "الØالة" #: editor/plugins/version_control_editor_plugin.cpp msgid "View file diffs before committing them to the latest version" -msgstr "" +msgstr "إظهار آخر تعديلات المل٠قبل قبولهم ÙÙŠ آخر نسخة." #: editor/plugins/version_control_editor_plugin.cpp msgid "No file diff is active" @@ -8833,172 +8712,152 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" -msgstr "" +msgstr "(GLES3 Ùقط)" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add Output" -msgstr "أض٠مدخله" +msgstr "إضاÙØ© Ù…Ùخرج" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "تكبير/تصغير:" +msgstr "كمية قياسية Scalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vector" -msgstr "متجه" +msgstr "Ù…Ùتجه" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "منطق Boolean" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sampler" msgstr "عينات (صوتية)" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "أض٠مدخله" +msgstr "أض٠بوابة المÙدخلات" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "أض٠منÙØ° المÙخرجات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "غير النوع الإÙتراضي" +msgstr "غيّر نوع منÙØ° المÙدخلات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "غير النوع الإÙتراضي" +msgstr "غيّر نوع منÙØ° المÙخرجات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "تغيير إسم الØركة:" +msgstr "غيّر اسم منÙØ° المÙدخلات" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Change output port name" -msgstr "" +msgstr "غيّر اسم منÙØ° المÙخرجات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "إزالة منÙØ° المÙدخلات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "إزالة منÙØ° المÙخرجات" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "النسخة الØالية:" +msgstr "تØديد التعبير" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Resize VisualShader node" -msgstr "" +msgstr "تغيير Øجم عÙقدة VisualShader (التظليل البصري)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" -msgstr "" +msgstr "تØديد اسم موØد" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set Input Default Port" -msgstr "Øدد كإÙتراضي من أجل '%s'" +msgstr "تØديد منÙØ° المدخلات الاÙتراضي" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add Node to Visual Shader" -msgstr "" +msgstr "إضاÙØ© عÙقدة للتظليل البصري Visual Shader" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Duplicate Nodes" -msgstr "Ù…ÙØ§ØªÙŠØ Ù†Ø³Ø® التØريك" +msgstr "مضاعÙØ© العÙقد" #: editor/plugins/visual_shader_editor_plugin.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Paste Nodes" -msgstr "" +msgstr "لصق العÙقد" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Nodes" -msgstr "إنشاء عقدة" +msgstr "Øذ٠العÙقد" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Input Type Changed" -msgstr "" +msgstr "تعدل نوع Ù…Ùدخلات التظليل البصري Visual Shader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" -msgstr "" +msgstr "رأس" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Fragment" -msgstr "البراهين:" +msgstr "شظايا" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Light" -msgstr "" +msgstr "ضوء" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Show resulted shader code." -msgstr "إنشاء عقدة" +msgstr "إظهار نص التظليل البرمجي الناتج." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "إنشاء عقدة" +msgstr "إنشاء عÙقدة تظليل" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ù‡Ù…Ø©" +msgstr "الوظيÙØ© البرمجية للون." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Ù…Ùشغّل اللون." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "إصنع دالة" +msgstr "وظيÙØ© التدرج الرمادي." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "تØويل Ù…Ùتجه HSV إلى معادله من RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "تØويل Ù…Ùتجه RGB إلى معادله من HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "إصنع دالة" +msgstr "وظيÙØ© البÙني الداكن." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Ù…Ùشغل الØرق." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Ù…Ùشغل التعتيم." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "الإختلاÙات Ùقط" +msgstr "Ù…Ùشغل الÙارق." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." @@ -9006,154 +8865,159 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator." -msgstr "" +msgstr "Ù…Ùشغل الضوء الساطع." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Ù…Ùشغل التÙتيØ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Ù…Ùشغل التراكم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Ù…Ùشغل الشاشة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Ù…Ùشغل الضوء الخاÙت." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "ثابت" +msgstr "ثابت اللون." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "تØويل تغيير التØريك" +msgstr "اللون المÙÙˆØد." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the boolean result of the %s comparison between two parameters." -msgstr "" +msgstr "ÙŠÙرجع المنطق الناتج عن مقارنة %s بين اثنين من المÙعاملات." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Equal (==)" -msgstr "" +msgstr "ÙŠÙعادل (==)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than (>)" -msgstr "" +msgstr "أكبر من (>)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than or Equal (>=)" -msgstr "" +msgstr "أكبر أو يساوي (>=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"ÙŠÙرجع المÙتجه المقرون إذا كانت القيمة القياسية المÙقدمة مساوية، أكبر أو أصغر." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between INF and a scalar " "parameter." msgstr "" +"ÙŠÙرجع قيمة المنطق (صØ/خطأ) من المقارنة بين INF ومَعلم الكمية القياسية scalar " +"parameter." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between NaN and a scalar " "parameter." msgstr "" +"ÙŠÙرجع منطق المقارنة (صØÙŠØ/خاطئ) بين NaN (ليس عدداً) Ùˆ مَعلم الكمية القياسية " +"scalar parameter." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than (<)" -msgstr "" +msgstr "أصغر من (<)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than or Equal (<=)" -msgstr "" +msgstr "أصغر أو يساوي (<=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Not Equal (!=)" -msgstr "" +msgstr "لا ÙŠÙعادل (!=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." -msgstr "" +msgstr "ÙŠÙرجع المٌتجه المقرون إن كانت قيمة المنطق المزود صØÙŠØØ© أو خاطئة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated scalar if the provided boolean value is true or false." msgstr "" +"ÙŠÙرجع قيمة الكمية القياسية scalar المقرونة إن كانت قيمة المنطق المزود صØÙŠØØ© " +"أو خاطئة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the boolean result of the comparison between two parameters." -msgstr "" +msgstr "ÙŠÙرجع نتيجة المنطق (صØÙŠØ/خاطئ) بعد المقارنة بين اثنين من المعالم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between INF (or NaN) and a " "scalar parameter." msgstr "" +"ÙŠÙرجع نتيجة المنطق (صØÙŠØ/خاطئ) الناتج عن المقارنة ما بين INF (أو NaN \"ليس " +"عدداً\") Ùˆ مَعلم كمية قياسية scalar parameter." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean constant." -msgstr "" +msgstr "ثابت المنطق (صØÙŠØ/خاطئ)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" +msgstr "المنطق (صØÙŠØ/خاطئ) المÙÙˆØد." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for all shader modes." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل جميع أساليب التظليل shader modes." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "الكبس إلي الطÙÙ„" +msgstr "مَعلم المÙدخل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader modes." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل أساليب تظليل الرأس والقطع." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment and light shader modes." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل أساليب تظليل القطع والإضاءة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment shader mode." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل أساليب تظليل القطع." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for light shader mode." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأسلوب تظليل الإضاءة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex shader mode." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل تظليل الرأس vertex." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader mode." -msgstr "" +msgstr "'%s' مَعلم المÙدخل لأجل أساليب تظليل الرأس والقÙطع." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "تكبير المØدد" +msgstr "وظيÙØ© الكمية القياسية Scalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Scalar operator." -msgstr "" +msgstr "Ù…Ùشغل الكمية القياسية Scalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." msgstr "" -"ثابت E ويعادل القيمة (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي." +"الثابت E وتعادل قيمته (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." @@ -9189,141 +9053,142 @@ msgstr "ÙŠØسب القيمة المطلقة لقيمة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة جيب التمام \"arc-cosine\" للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة جيب تمام القطع الزائد العكسي للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة الجيب العكسية للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة جيب القطع الزائد العكسي للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة ظل الزاوية العكسية \"arc-tangent\" للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "ÙŠÙرجع قيمة ظل الزاوية العكسي \"arc-tangent\" للمعالم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic tangent of the parameter." msgstr "" +"ÙŠÙرجع قيمة ظل الزاوية العكسي (قطع زائد) \"inverse hyperbolic tangent\" للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "يجد أقرب رقم أكبر أو يساوي المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "ÙŠÙجبر قيمة على التوضع بين قيميتن إضاÙيتين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع جيب التمام \"cosine \" لقيمة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة جيب التمام الزائدي \"hyperbolic cosine\" لقيمة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "ÙŠØوّل قيمة (كمية) من الراديان إلى الدرجات." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "الدالة Base-e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "الدالة Base-2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "يجد أقرب رقم أصغر أو يساوي المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "ÙŠØسب الجزء الكسري من المعامل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "ÙŠÙرجع عكس قيمة الجذر التربيعي للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "اللوغاريتم الطبيعي." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "اللوغاريتم Base-2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "ÙŠÙرجع القيمة الكÙبرى بين القيمتين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "ÙŠÙرجع القيمة الأصغر بين القيمتين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "استيÙاء (استقراء داخلي interpolation ) خطي بين كميتين قياسيتين scalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "ÙŠÙرجع القيمة المعاكسة للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - الكمية القياسية" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "ÙŠÙرجع قيمة المَعلم الأول مرÙوعاً إلى قوّة الثاني." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "ÙŠØول الكمية المقاسة بالدرجات إلى الراديان." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 \\ الكمية القياسية" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer to the parameter." -msgstr "" +msgstr "يوجد الرقم الأقرب للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest even integer to the parameter." -msgstr "" +msgstr "يجد العدد الزوجي الأقرب لقيمة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "ÙŠÙمخلب (ÙŠØصر) القيمة بين 0.0 Ùˆ 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "يستخرج إشارة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع جيب sine المَعلم parameter." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة الجيب العكس hyperbolic sine للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة الجذر التربيعي للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9333,6 +9198,12 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"الوظيÙØ© البرمجية \"الخطوة الناعمة\" SmoothStep وهي function( scalar(edge0), " +"scalar(edge1), scalar(x) ).\n" +"\n" +"تÙرجع 0.0 إذا كان 'x' أصغر من 'edge0' Ùˆ 1.0 إذا كان x أكبر من 'edge1'. عدا " +"ذلك سيتم استيÙاء (استقراء داخلي interpolated) للقيمة ما بين 0.0 Ùˆ 1.0 " +"باستخدام متعددات الØدود لهيرمت Hermite polynomials." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9340,42 +9211,45 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." msgstr "" +"الوظيÙØ© البرمجية \"الخطوة\" function( scalar(edge), scalar(x) ).\n" +"\n" +"تÙرجع 0.0 إذا كان 'x' أصغر من 'edge' وعدا ذلك 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة ظل الزاوية tangent للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "ÙŠÙرجع قيمة ظل الزاوية العكسي hyperbolic tangent للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the truncated value of the parameter." -msgstr "" +msgstr "يجد قيمة الاقتطاع truncated للمَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "إضاÙØ© كمية قياسية إلى كمية قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "تقسيم كمية قياسية على كمية قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "الضرب الرياضي لكمية قياسية بكمية قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "ÙŠÙرجع باقي الكميتين القياسيتين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Ø·Ø±Ø ÙƒÙ…ÙŠØ© قياسية من كمية قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Scalar constant." -msgstr "" +msgstr "ثابت الكمية القياسية Scalar constant." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9384,28 +9258,28 @@ msgstr "تØويل تغيير التØريك" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "إجراء البØØ« عن النقش المكعبي." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "إجراء البØØ« عن النقش." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Cubic texture uniform lookup." -msgstr "" +msgstr "البØØ« عن النقش المكعبي الموØد." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "2D texture uniform lookup." -msgstr "" +msgstr "البØØ« عن النقش الموØد ثنائي البÙعد." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "2D texture uniform lookup with triplanar." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "إنشاء بولي" +msgstr "وظيÙØ© التØويل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9420,70 +9294,67 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "تألي٠التØوّل من أربع Ù…Ùتجهات vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Ùكّ التØوّل إلى أربع Ù…Ùتجهات vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the determinant of a transform." -msgstr "" +msgstr "Øساب Ù…ÙØدد determinant التØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the inverse of a transform." -msgstr "" +msgstr "Øساب عكس التØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the transpose of a transform." -msgstr "" +msgstr "Øساب تبدل موضع التØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "مضاعÙØ© التØوّلات بالتØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Ù…ÙضاعÙØ© المÙتجهات بالتØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "إنشاء بولي" +msgstr "ثابت التØوّل." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "إنشاء بولي" +msgstr "Ù…ÙÙˆØد التØوّل Transform uniform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "التعيين لتعمل." +msgstr "وظيÙØ© المÙتجه Vector ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vector operator." -msgstr "" +msgstr "Ù…Ùشغّل المÙتجه." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "تألي٠المÙتجه من ثلاث كميات قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Ùكّ تركيب المÙتجه إلى ثلاث كميات قياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Øساب المنتوج الوسيط للمÙتجهين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "ÙŠÙرجع المساÙØ© ما بين نقطتين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Øساب الجداء السلمي dot product للمÙتجهين (الشعاعين)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9495,15 +9366,17 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Øساب طول المÙتجه (الشعاع)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "الاستيÙاء (الاستقراء الداخلي interpolation ) بين Ù…Ùتجهين." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors using scalar." msgstr "" +"الاستيÙاء (الاستقراء الداخلي interpolation) بين Ù…Ùتجهين باستخدام الكمية " +"القياسية." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." @@ -9655,43 +9528,43 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" -msgstr "" +msgstr "المÙظلل البصري" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Edit Visual Property" -msgstr "تعديل المصاÙÙŠ" +msgstr "تØرير الخاصية البصرية" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Mode Changed" -msgstr "" +msgstr "تغيير وضع المÙظلل البصري" #: editor/project_export.cpp msgid "Runnable" -msgstr "" +msgstr "قابل للتشغيل" #: editor/project_export.cpp -#, fuzzy msgid "Add initial export..." -msgstr "أض٠مدخله" +msgstr "إضاÙØ© تصدير مبدئي..." #: editor/project_export.cpp msgid "Add previous patches..." -msgstr "" +msgstr "إضاÙØ© الرÙقع السابقة..." #: editor/project_export.cpp msgid "Delete patch '%s' from list?" -msgstr "" +msgstr "Øذ٠رÙقعة '%s' من القائمة؟" #: editor/project_export.cpp msgid "Delete preset '%s'?" -msgstr "" +msgstr "Øذ٠المÙعد Ù…Ùسبقاً '%s'ØŸ" #: editor/project_export.cpp msgid "" "Failed to export the project for platform '%s'.\n" "Export templates seem to be missing or invalid." msgstr "" +"أخÙÙ‚ تصدير المشروع لمنصة '%s'.\n" +"على ما يبدو قوالب التصدير Ù…Ùقودة أو غير صالØØ©." #: editor/project_export.cpp msgid "" @@ -9699,165 +9572,165 @@ msgid "" "This might be due to a configuration issue in the export preset or your " "export settings." msgstr "" +"أخÙÙ‚ تصدير المشروع لمنصة '%s'.\n" +"قد يعود ذلك إلى خلل تهيئة ÙÙŠ الإعدادات المÙعدّة سلÙاً أو إعدادات التصدير الخاصة " +"بك." #: editor/project_export.cpp msgid "Release" -msgstr "" +msgstr "الإصدار" #: editor/project_export.cpp -#, fuzzy msgid "Exporting All" -msgstr "التصدير كـ %s" +msgstr "تصدير الكÙÙ„" #: editor/project_export.cpp -#, fuzzy msgid "The given export path doesn't exist:" -msgstr "هذا المسار غير موجود." +msgstr "مسار التصدير المÙزود غير موجود:" #: editor/project_export.cpp msgid "Export templates for this platform are missing/corrupted:" -msgstr "" +msgstr "قوالب تصدير هذه المنصة Ù…Ùقودة / تالÙØ©:" #: editor/project_export.cpp msgid "Presets" -msgstr "" +msgstr "Ù…Ùعد سلÙاً" #: editor/project_export.cpp editor/project_settings_editor.cpp msgid "Add..." -msgstr "" +msgstr "إضاÙØ©..." #: editor/project_export.cpp msgid "" "If checked, the preset will be available for use in one-click deploy.\n" "Only one preset per platform may be marked as runnable." msgstr "" +"إن تم تØدديها، ستتم إتاØØ© المÙعدّة سلÙاً لتكون جاهزة للنشر deploy بضغط واØدة.\n" +"Ùقط واØدة من المÙعدّة سلÙاً preset لكل منصة ستوسم على أنها قابلة للتشغيل." #: editor/project_export.cpp -#, fuzzy msgid "Export Path" -msgstr "تصدير المشروع" +msgstr "مسار التصدير" #: editor/project_export.cpp msgid "Resources" -msgstr "" +msgstr "الموراد" #: editor/project_export.cpp msgid "Export all resources in the project" -msgstr "" +msgstr "تصدير جميع الموارد ÙÙŠ المشروع" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" -msgstr "" +msgstr "تصدير المشاهد المÙختارة (وتبعاتها)" #: editor/project_export.cpp msgid "Export selected resources (and dependencies)" -msgstr "" +msgstr "تصدير الموارد المÙختارة (وتبعياتها)" #: editor/project_export.cpp msgid "Export Mode:" -msgstr "" +msgstr "وضع التصدير:" #: editor/project_export.cpp msgid "Resources to export:" -msgstr "" +msgstr "الموارد المÙعدّة للتصدير:" #: editor/project_export.cpp msgid "" "Filters to export non-resource files/folders\n" "(comma-separated, e.g: *.json, *.txt, docs/*)" msgstr "" +"Ù…ÙرشØات Filters تصدير الملÙات / المجلدات من غير الموارد\n" +"(تلك المÙصولة بالÙاصلة، على سبيل المثال: *.json, *.txt, docs/*)" #: editor/project_export.cpp msgid "" "Filters to exclude files/folders from project\n" "(comma-separated, e.g: *.json, *.txt, docs/*)" msgstr "" +"Ù…ÙرشØات Filters تصدير الملÙات/المÙجلدات من المشروع\n" +"(المÙصولة بÙاصلة، مثلاً: *.json, *.txt, docs/*)" #: editor/project_export.cpp msgid "Patches" -msgstr "" +msgstr "الرÙقع Patches" #: editor/project_export.cpp msgid "Make Patch" -msgstr "" +msgstr "إنشاء رÙقعة Patch" #: editor/project_export.cpp -#, fuzzy msgid "Pack File" -msgstr " ملÙات" +msgstr "مل٠الØÙزمة" #: editor/project_export.cpp msgid "Features" -msgstr "" +msgstr "المزايا" #: editor/project_export.cpp msgid "Custom (comma-separated):" -msgstr "" +msgstr "Ù…Ùخصص (Ù…Ùصول بÙاصلة):" #: editor/project_export.cpp msgid "Feature List:" -msgstr "" +msgstr "قائمة المزايا:" #: editor/project_export.cpp -#, fuzzy msgid "Script" -msgstr "تشغيل الكود" +msgstr "النص البرمجي" #: editor/project_export.cpp -#, fuzzy msgid "Script Export Mode:" -msgstr "تصدير المشروع" +msgstr "وضع تصدير النص البرمجي:" #: editor/project_export.cpp msgid "Text" -msgstr "" +msgstr "نص" #: editor/project_export.cpp msgid "Compiled" -msgstr "" +msgstr "Ù…ÙØولة برمجياً" #: editor/project_export.cpp msgid "Encrypted (Provide Key Below)" -msgstr "" +msgstr "مشÙّرة (قدّم المÙØªØ§Ø Ø£Ø¯Ù†Ø§Ù‡)" #: editor/project_export.cpp msgid "Invalid Encryption Key (must be 64 characters long)" -msgstr "" +msgstr "Ù…ÙØªØ§Ø ØªØ´Ùير غير ØµØ§Ù„Ø (ينبغي أن يكون طوله 46 ØرÙ)" #: editor/project_export.cpp msgid "Script Encryption Key (256-bits as hex):" -msgstr "" +msgstr "Ù…ÙØªØ§Ø ØªØ´Ùير النص البرمجي (256-bits Ùƒ hex ):" #: editor/project_export.cpp msgid "Export PCK/Zip" -msgstr "" +msgstr "تصدير PCK/ مل٠مضغوط Zip" #: editor/project_export.cpp msgid "Export Project" msgstr "تصدير المشروع" #: editor/project_export.cpp -#, fuzzy msgid "Export mode?" -msgstr "تصدير المشروع" +msgstr "وضع التصدير؟" #: editor/project_export.cpp -#, fuzzy msgid "Export All" -msgstr "تصدير" +msgstr "تصدير الكÙÙ„" #: editor/project_export.cpp editor/project_manager.cpp -#, fuzzy msgid "ZIP File" -msgstr " ملÙات" +msgstr "المل٠المضغوط ZIP File" #: editor/project_export.cpp msgid "Godot Game Pack" -msgstr "" +msgstr "رÙزمة لعبة غودوت" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" -msgstr "" +msgstr "قوالب التصدير لهذه المنصة Ù…Ùقودة:" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -9865,47 +9738,44 @@ msgstr "إدارة قوالب التصدير" #: editor/project_export.cpp msgid "Export With Debug" -msgstr "" +msgstr "التصدير مع Ù…ÙÙ†Ù‚Ø Ø§Ù„Ø£Ø®Ø·Ø§Ø¡" #: editor/project_manager.cpp -#, fuzzy msgid "The path specified doesn't exist." -msgstr "هذا المسار غير موجود." +msgstr "المسار المÙØدد غير موجود." #: editor/project_manager.cpp -#, fuzzy msgid "Error opening package file (it's not in ZIP format)." msgstr "Øدث خطأ عندÙØªØ Ù…Ù„Ù Ø§Ù„Øزمة بسبب أن المل٠ليس ÙÙŠ صيغة \"ZIP\"." #: editor/project_manager.cpp msgid "" "Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." -msgstr "" +msgstr "مل٠المشروع \".zip\" غير صالØØ› لا ÙŠØوي مل٠\"project.godot\"." #: editor/project_manager.cpp msgid "Please choose an empty folder." -msgstr "" +msgstr "من Ùضلك اختر Ù…Ùجلداً Ùارغاً." #: editor/project_manager.cpp msgid "Please choose a \"project.godot\" or \".zip\" file." -msgstr "" +msgstr "من Ùضلك اختر مل٠\"project.godot\" أو \".zip\"." #: editor/project_manager.cpp msgid "This directory already contains a Godot project." -msgstr "" +msgstr "الدليل المÙختار يتضمن بالÙعل مشروعاً لغودوت." #: editor/project_manager.cpp msgid "New Game Project" -msgstr "" +msgstr "مشروع لعبة جديد" #: editor/project_manager.cpp msgid "Imported Project" -msgstr "" +msgstr "المشاريع المستوردة" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "اسم غير صالØ." +msgstr "اسم مشروع غير صالØ." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -9913,37 +9783,38 @@ msgstr "لا يمكن إنشاء المجلد." #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." -msgstr "" +msgstr "يوجد مل٠بالÙعل بالمسار المÙختار بذات الاسم المÙختار." #: editor/project_manager.cpp msgid "It would be a good idea to name your project." -msgstr "" +msgstr "إنها Ù„Ùكرة جيدة أن تقوم بتسمية مشروعك." #: editor/project_manager.cpp msgid "Invalid project path (changed anything?)." -msgstr "" +msgstr "مسار مشروع غير ØµØ§Ù„Ø (أعدلت شيء؟)." #: editor/project_manager.cpp msgid "" "Couldn't load project.godot in project path (error %d). It may be missing or " "corrupted." msgstr "" +"لم يتم تØميل project.godot من مسار المشروع (خطأ %d). قد يكون Ù…Ùقوداً أو تالÙاً." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." -msgstr "" +msgstr "لا قدرة على تØرير project.godot ÙÙŠ مسار المشروع." #: editor/project_manager.cpp msgid "Couldn't create project.godot in project path." -msgstr "" +msgstr "لا قدرة على إنشاء project.godot ÙÙŠ مسار المشروع." #: editor/project_manager.cpp msgid "Rename Project" -msgstr "" +msgstr "إعادة تسمية المشروع" #: editor/project_manager.cpp msgid "Import Existing Project" -msgstr "" +msgstr "استيراد مشروع موجود" #: editor/project_manager.cpp msgid "Import & Edit" @@ -9951,7 +9822,7 @@ msgstr "إستيراد Ùˆ تعديل" #: editor/project_manager.cpp msgid "Create New Project" -msgstr "" +msgstr "إنشاء مشروع جديد" #: editor/project_manager.cpp msgid "Create & Edit" @@ -9959,7 +9830,7 @@ msgstr "إنشاء Ùˆ تعديل" #: editor/project_manager.cpp msgid "Install Project:" -msgstr "" +msgstr "تنصيب المشروع:" #: editor/project_manager.cpp msgid "Install & Edit" @@ -9967,23 +9838,23 @@ msgstr "تثبيت Ùˆ تعديل" #: editor/project_manager.cpp msgid "Project Name:" -msgstr "" +msgstr "اسم المشروع:" #: editor/project_manager.cpp msgid "Project Path:" -msgstr "" +msgstr "مسار المشروع:" #: editor/project_manager.cpp msgid "Project Installation Path:" -msgstr "" +msgstr "مسار تنصيب المشروع:" #: editor/project_manager.cpp msgid "Renderer:" -msgstr "" +msgstr "Ù…ÙØرك الإخراج البصري:" #: editor/project_manager.cpp msgid "OpenGL ES 3.0" -msgstr "" +msgstr "OpenGL ES 3.0" #: editor/project_manager.cpp msgid "" @@ -9992,10 +9863,14 @@ msgid "" "Incompatible with older hardware\n" "Not recommended for web games" msgstr "" +"قيمة بصرية أعلى\n" +"جميع المزايا متواÙرة\n" +"غير متواÙÙ‚ مع العتاد القديم\n" +"ليس نصØية بالنسبة لألعاب الويب" #: editor/project_manager.cpp msgid "OpenGL ES 2.0" -msgstr "" +msgstr "OpenGL ES 2.0" #: editor/project_manager.cpp msgid "" @@ -10004,32 +9879,35 @@ msgid "" "Works on most hardware\n" "Recommended for web games" msgstr "" +"قيمة بصرية أقل\n" +"بعض المزايا غير متواÙرة \n" +"يعمل على أغلب العتاد\n" +"نصيØØ© لألعاب الويب" #: editor/project_manager.cpp msgid "Renderer can be changed later, but scenes may need to be adjusted." msgstr "" +"Ù…ÙØرك الإخراج البصري يمكن تغييره لاØقاً، ولكن قد تØتاج إلى تعديل المشاهد." #: editor/project_manager.cpp msgid "Unnamed Project" -msgstr "" +msgstr "مشروع غير مسمى" #: editor/project_manager.cpp -#, fuzzy msgid "Missing Project" -msgstr "بناء المشروع" +msgstr "مشروع Ù…Ùقود" #: editor/project_manager.cpp msgid "Error: Project is missing on the filesystem." -msgstr "" +msgstr "خطأ: المشروع Ù…Ùقود ÙÙŠ ملÙات النظام." #: editor/project_manager.cpp -#, fuzzy msgid "Can't open project at '%s'." -msgstr "لا يمكن ÙØªØ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹" +msgstr "لا يمكن ÙØªØ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ ÙÙŠ '%s'." #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" -msgstr "" +msgstr "هل أنت واثق من ÙØªØ Ø£ÙƒØ«Ø± من مشروع؟" #: editor/project_manager.cpp msgid "" @@ -10061,188 +9939,208 @@ msgid "" "The project settings were created by a newer engine version, whose settings " "are not compatible with this version." msgstr "" +"لقد تم إنشاء إعدادات المشروع هذا بإصدار Ø£Øدث من المÙØرك، تلك الإعدادات غير " +"متواÙقة مع هذا الإصدار." #: editor/project_manager.cpp -#, fuzzy msgid "" "Can't run project: no main scene defined.\n" "Please edit the project and set the main scene in the Project Settings under " "the \"Application\" category." msgstr "" -"لا مشهد أساسي تم تØديده، Øدد واØد؟\n" -"يمكنك تغييره لاØقاً ÙÙŠ \"إعدادات المشروع\" تØت قسم 'التطبيق'." +"لا يمكن تشغيل المشروع: لم يتم تØديد مشهد رئيس.\n" +"من Ùضلك Øرر المشروع ÙˆØدد مشهداً رئيساً ÙÙŠ إعدادات المشروع تØت خيار \"التطبيق\"." #: editor/project_manager.cpp msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" +"لا يمكن تشغيل المشروع: يجب استيراد المÙÙ„Øقات.\n" +"من Ùضلك Øرر المشروع لتØريض الشروع بالاستيراد." #: editor/project_manager.cpp msgid "Are you sure to run %d projects at once?" -msgstr "" +msgstr "هل أنت متأكد من ÙØªØ %d مشاريع مرّة واØدة؟" #: editor/project_manager.cpp msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." msgstr "" +"إزالة %d مشاريع من القائمة؟\n" +"لن يتم تعديل Ù…Øتويات Ù…Ùجلدات المشاريع." #: editor/project_manager.cpp msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." msgstr "" +"إزالة هذا المشروع من القائمة؟\n" +"لن يتم تعديل Ù…Øتوى Ù…Ùجلد المشروع." #: editor/project_manager.cpp msgid "" "Remove all missing projects from the list?\n" "The project folders' contents won't be modified." msgstr "" +"إزالة جميع المشاريع المÙقودة من القائمة؟\n" +"لن يتم تعديل Ù…Øتوى Ù…Ùجلدات المشاريع." #: editor/project_manager.cpp msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" +"تم تغيير اللÙغة.\n" +"ستتØدث الواجهة بعد إعادة تشغيل المÙØرر أو Ù…Ùدير المشاريع." #: editor/project_manager.cpp msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" +"هل أنت متأكد من ÙØص %s من المجلدات بØثاً عن مشاريع غودوت متواÙرة؟\n" +"قد يستغرق وقتاً." #: editor/project_manager.cpp msgid "Project Manager" msgstr "مدير المشروع" #: editor/project_manager.cpp -#, fuzzy msgid "Projects" -msgstr "مشروع" +msgstr "المشاريع" #: editor/project_manager.cpp msgid "Last Modified" -msgstr "" +msgstr "آخر ما تم تعديله" #: editor/project_manager.cpp msgid "Scan" -msgstr "" +msgstr "ÙØص" #: editor/project_manager.cpp msgid "Select a Folder to Scan" -msgstr "" +msgstr "اختر Ù…Ùجلداً Ù„ÙØصه" #: editor/project_manager.cpp msgid "New Project" -msgstr "" +msgstr "مشروع جديد" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø·Ø©" +msgstr "إزالة المÙقود" #: editor/project_manager.cpp msgid "Templates" -msgstr "" +msgstr "القوالب" #: editor/project_manager.cpp msgid "Restart Now" -msgstr "" +msgstr "إعادة التشغيل الآن" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "" +msgstr "غير قادر على تشغيل المشروع" #: editor/project_manager.cpp msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" +"لا تملك Øالياً أية مشاريع.\n" +"هل ترغب ÙÙŠ استكشا٠مشاريع الأمثلة الرسمية ÙÙŠ مكتبة المÙÙ„Øقات؟" + +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" #: editor/project_settings_editor.cpp msgid "Key " -msgstr "" +msgstr "زر " #: editor/project_settings_editor.cpp msgid "Joy Button" -msgstr "" +msgstr "زر Joy" #: editor/project_settings_editor.cpp msgid "Joy Axis" -msgstr "" +msgstr "Ù…Øور Joy" #: editor/project_settings_editor.cpp msgid "Mouse Button" -msgstr "" +msgstr "زر الÙأرة" #: editor/project_settings_editor.cpp msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" +"اسم Ùعالية غير صØÙŠØ. لا يمكن أن يكون Ùارغاً أو أو يتضمن '/'ØŒ ':'ØŒ '='ØŒ '\\' " +"أو '\"'" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "خطأ: إسم الØركة موجود بالÙعل!" +msgstr "Ùعالية action بهذا الاسم '%s' موجودة سلÙاً." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" -msgstr "" +msgstr "إعادة تسمية Øدث Ùعالية الإدخال" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Change Action deadzone" -msgstr "تغيير إسم الØركة:" +msgstr "تغيير المنطقة الميتة للÙعالية Action deadzone" #: editor/project_settings_editor.cpp msgid "Add Input Action Event" -msgstr "" +msgstr "إضاÙØ© Øدث Ùعالية الإدخال" #: editor/project_settings_editor.cpp msgid "All Devices" -msgstr "" +msgstr "جميع الأجهزة" #: editor/project_settings_editor.cpp msgid "Device" -msgstr "" +msgstr "الجهاز" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Press a Key..." -msgstr "" +msgstr "اضغط زراً..." #: editor/project_settings_editor.cpp msgid "Mouse Button Index:" -msgstr "" +msgstr "مؤشر Index زر الÙأرة:" #: editor/project_settings_editor.cpp msgid "Left Button" -msgstr "" +msgstr "الزر الأيسر" #: editor/project_settings_editor.cpp msgid "Right Button" -msgstr "" +msgstr "الزر الأيمن" #: editor/project_settings_editor.cpp msgid "Middle Button" -msgstr "" +msgstr "الزر الأوسط" #: editor/project_settings_editor.cpp msgid "Wheel Up Button" -msgstr "" +msgstr "زر العجلة للأعلى" #: editor/project_settings_editor.cpp msgid "Wheel Down Button" -msgstr "" +msgstr "زر العجلة للأسÙÙ„" #: editor/project_settings_editor.cpp msgid "Wheel Left Button" -msgstr "" +msgstr "زر العجلة يساراً" #: editor/project_settings_editor.cpp msgid "Wheel Right Button" -msgstr "" +msgstr "زر العجلة يميناً" #: editor/project_settings_editor.cpp msgid "X Button 1" @@ -10278,7 +10176,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Button" -msgstr "" +msgstr "زر" #: editor/project_settings_editor.cpp msgid "Left Button." @@ -10551,9 +10449,8 @@ msgid "Suffix" msgstr "" #: editor/rename_dialog.cpp -#, fuzzy msgid "Use Regular Expressions" -msgstr "النسخة الØالية:" +msgstr "استخدام التعبيرات الاعتيادية Regular Expressions" #: editor/rename_dialog.cpp #, fuzzy @@ -10663,9 +10560,8 @@ msgid "Regular Expression Error" msgstr "" #: editor/rename_dialog.cpp -#, fuzzy msgid "At character %s" -msgstr "الأØر٠الصالØØ©:" +msgstr "عند الØر٠%s" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent Node" @@ -11273,9 +11169,8 @@ msgid "Profiler" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Network Profiler" -msgstr "تصدير المشروع" +msgstr "مل٠تعري٠الشبكة Network Profiler" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -11302,6 +11197,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "تصدير الملÙ" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" @@ -11381,7 +11281,7 @@ msgstr "" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "" +msgstr "غيّر Øجم الكاميرا" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -12159,80 +12059,88 @@ msgstr "إخلاء الكود" #: modules/visual_script/visual_script_property_selector.cpp msgid "Get %s" -msgstr "" +msgstr "جلب %s" #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" -msgstr "" +msgstr "تØديد %s" #: platform/android/export/export.cpp msgid "Package name is missing." -msgstr "" +msgstr "اسم الرÙزمة Ù…Ùقود." #: platform/android/export/export.cpp msgid "Package segments must be of non-zero length." -msgstr "" +msgstr "أقسام الرÙزمة ينبغي أن تكون ذات مساÙات غير-صÙرية non-zero length." #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." -msgstr "" +msgstr "إن الØر٠'%s' غير Ù…Ø³Ù…ÙˆØ ÙÙŠ أسماء ØÙزم تطبيقات الأندرويد." #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." -msgstr "" +msgstr "لا يمكن أن يكون الرقم هو أول Øر٠ÙÙŠ مقطع الرÙزمة." #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." -msgstr "" +msgstr "الØر٠'%s' لا يمكن أن يكون الØر٠الأول من مقطع الرÙزمة." #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." -msgstr "" +msgstr "يجب أن تتضمن الرزمة على الأقل واØد من الÙواصل '.' ." #: platform/android/export/export.cpp msgid "Select device from the list" -msgstr "اختار جهاز من القائمة" +msgstr "اختر جهازاً من القائمة" #: platform/android/export/export.cpp msgid "ADB executable not configured in the Editor Settings." -msgstr "" +msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات المÙØرر." #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." msgstr "" +"‌مÙوقّع ملÙات الجار jarsigner المÙØªÙˆØ Ø§Ù„Ø®Ø§Øµ بØزمة التطوير OpenJDK غير Ù…Ùهيّئ ÙÙŠ " +"إعدادات المÙØرر." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." msgstr "" +"Ù…ÙÙ†Ù‚Ø Ø£Ø®Ø·Ø§Ø¡ Ù…ÙØªØ§Ø Ø§Ù„Ù…ØªØ¬Ø± keystore غير Ù…Ùهيئ ÙÙŠ إعدادت المÙØرر أو ÙÙŠ الإعدادات " +"الموضوعة سلÙاً." #: platform/android/export/export.cpp msgid "Custom build requires a valid Android SDK path in Editor Settings." msgstr "" +"البÙنى المخصوصة تتطلب مساراً Ù„Øزمة تطوير Android SDK صالØØ© ÙÙŠ إعدادات المÙØرر." #: platform/android/export/export.cpp msgid "Invalid Android SDK path for custom build in Editor Settings." msgstr "" +"مسار Øزمة تطوير Android SDK للبÙنى المخصوصة، غير ØµØ§Ù„Ø ÙÙŠ إعدادات المÙØرر." #: platform/android/export/export.cpp msgid "" "Android build template not installed in the project. Install it from the " "Project menu." msgstr "" +"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل واØداً من قائمة المشروع." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." -msgstr "" +msgstr "Ù…ÙØªØ§Ø Ø¹Ø§Ù… غير ØµØ§Ù„Ø Ù„Ø£Ø¬Ù„ تصدير Øزمة تطبيق أندرويد APK." #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid package name:" -msgstr "إسم صن٠غير صالØ" +msgstr "اسم رÙزمة غير صالØ:" #: platform/android/export/export.cpp msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" +"تتم Ù…Øاولة البناء من قالب بناء Ù…Ùخصص، ولكن لا تتواجد معلومات النسخة. من Ùضلك " +"أعد التØميل من قائمة \"المشروع\"." #: platform/android/export/export.cpp msgid "" @@ -12241,45 +12149,52 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"نسخ بناء Android غير متواÙقة:\n" +"\tقوالب Ù…Ùنصبة: %s\n" +"\tإصدار غودوت: %s\n" +"من Ùضلك أعد تنصيب قالب بناء الأندرويد Android من قائمة \"المشروع\"." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "بناء مشروع الأندرويد (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"أخÙÙ‚ بناء مشروع الأندرويد، تÙقد المÙخرجات للإطلاع على الخطأ.\n" +"بصورة بديلة يمكنك زيارة docs.godotengine.org لأجل مستندات البناء للأندرويد." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "لم يتم توليد Øزمة أندرويد apk ÙÙŠ: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." -msgstr "" +msgstr "المÙØدد Ù…Ùقود." #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." -msgstr "" +msgstr "إن الØر٠'%s' غير Ù…Ø³Ù…ÙˆØ ÙÙŠ المÙØدد Identifier." #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." msgstr "" +"لم يتم تØديد ID الÙÙرق الخاص بمتجر التطبيقات - لا يمكن تهيئة configure " +"المشروع." #: platform/iphone/export/export.cpp -#, fuzzy msgid "Invalid Identifier:" -msgstr "Øجم الخط غير صالØ" +msgstr "Ù…ÙØدد غير صالØ:" #: platform/iphone/export/export.cpp msgid "Required icon is not specified in the preset." -msgstr "" +msgstr "الأيقونة المطلوبة لم تÙØدد ÙÙŠ الإعدادات المÙسبقة." #: platform/javascript/export/export.cpp msgid "Stop HTTP Server" -msgstr "" +msgstr "إيقا٠مÙخدم HTTP" #: platform/javascript/export/export.cpp msgid "Run in Browser" @@ -12311,65 +12226,59 @@ msgstr "لا يمكن قراءة مل٠الإقلاع الصوري:" #: platform/javascript/export/export.cpp msgid "Using default boot splash image." -msgstr "" +msgstr "استخدام الصورة الاÙتراضية للشروع بالتشغيل." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package short name." -msgstr "إسم صن٠غير صالØ" +msgstr "اسم الرÙزمة القصير غير صالØ." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package unique name." -msgstr "اسم غير صالØ." +msgstr "الاسم المميز للرÙزمة غير صالØ." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package publisher display name." -msgstr "اسم غير صالØ." +msgstr "اسم الناشر المعروض للرÙزمة غير صالØ." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid product GUID." -msgstr "اسم غير صالØ." +msgstr "Ù…Ùعر٠GUID (المÙعرّ٠الÙريد العالمي) للمنتج غير صالØ." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid publisher GUID." -msgstr "مسار غير صالØ." +msgstr "المÙعر٠الÙريد العالمي للناشر GUID غير صالØ." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid background color." -msgstr "اسم غير صالØ." +msgstr "لون خلÙية غير صالØ." #: platform/uwp/export/export.cpp msgid "Invalid Store Logo image dimensions (should be 50x50)." -msgstr "" +msgstr "أبعاد صورة الشعار الخاص بالمتجر غير صالØØ© (ينبغي أن تكون50 × 50)." #: platform/uwp/export/export.cpp msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." -msgstr "" +msgstr "أبعاد صورة الشعار المربع 44×44 غير صالØØ© (ينبغي أن تكون 44×44)." #: platform/uwp/export/export.cpp msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." -msgstr "" +msgstr "أبعاد صورة شعار 71×71 غير صالØØ© (ينبغي أن تكون 71×71)." #: platform/uwp/export/export.cpp msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." -msgstr "" +msgstr "أبعاد صورة الشعار المÙربع 150×150 غير صالØØ© (ينبغي أن تكون 150×150)." #: platform/uwp/export/export.cpp msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." -msgstr "" +msgstr "أبعاد صورة الشعار المÙربع 310×310 غير صالØØ© (ينبغي أن تكون 310×310)." #: platform/uwp/export/export.cpp msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." -msgstr "" +msgstr "أبعاد صورة الشعار المربع 310x150 غير صالØØ© (ينبغي أن تكون 310x150)." #: platform/uwp/export/export.cpp msgid "Invalid splash screen image dimensions (should be 620x300)." -msgstr "" +msgstr "أبعاد شاشة البداية غير صالØØ© (ينبغي أن تكون 620×300)." #: scene/2d/animated_sprite.cpp #, fuzzy @@ -12402,7 +12311,7 @@ msgstr "" #: scene/2d/collision_polygon_2d.cpp msgid "An empty CollisionPolygon2D has no effect on collision." -msgstr "" +msgstr "Ù…Ùضلع تصادم ثنائي الأبعاد Ùارغ ليس له أي تأثير على التصادم." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -12494,6 +12403,8 @@ msgstr "" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." msgstr "" +"سلسلة العظم ثنائي البÙعد Bone2D هذه، ينبغي أن تنتهي ÙÙŠ عÙقدة هيكل ثنائي البÙعد " +"Skeleton2D." #: scene/2d/skeleton_2d.cpp msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." @@ -12547,11 +12458,11 @@ msgstr "" #: scene/3d/baked_lightmap.cpp msgid "%d%%" -msgstr "" +msgstr "%d%%" #: scene/3d/baked_lightmap.cpp msgid "(Time Left: %d:%02d s)" -msgstr "" +msgstr "(الوقت المتبقي: %d:%02d ثانية)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " @@ -12636,7 +12547,7 @@ msgstr "" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." -msgstr "" +msgstr "بقعة الضوء بزاوية أكبر من 90 درجة لا يمكنها إلقاء الظلال." #: scene/3d/navigation_mesh.cpp msgid "A NavigationMesh resource must be set or created for this node to work." @@ -12668,7 +12579,7 @@ msgstr "" #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." -msgstr "" +msgstr "يعمل تتبع المسار PathFollow Ùقط عندما يكون ابناً لعÙقدة مسار Path." #: scene/3d/path.cpp msgid "" @@ -12691,7 +12602,7 @@ msgstr "" #: scene/3d/soft_body.cpp msgid "This body will be ignored until you set a mesh." -msgstr "" +msgstr "سيتم تجاهل هذا الجسم Øتى تضع تØدد سطØاً mesh." #: scene/3d/soft_body.cpp msgid "" @@ -12737,45 +12648,43 @@ msgid "On BlendTree node '%s', animation not found: '%s'" msgstr "" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Animation not found: '%s'" -msgstr "أدوات الØركة" +msgstr "لم يتم إيجاد الرسم المتØرك: '%s'" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." -msgstr "" +msgstr "ÙÙŠ العÙقدة '%s'ØŒ رسومية متØركة غير صالØØ©: '%s'." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Invalid animation: '%s'." -msgstr "خطأ: إسم Øركة خاطئ!" +msgstr "رسومية متØركة غير صالØØ©: '%s'." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Nothing connected to input '%s' of node '%s'." -msgstr "قطع إتصال'%s' من '%s'" +msgstr "ليس هناك وصل بين أي من Ù…Ùدخلات '%s' للعÙقدة '%s'." #: scene/animation/animation_tree.cpp msgid "No root AnimationNode for the graph is set." -msgstr "" +msgstr "لم يتم تØديد عÙقدة رئيسة لعÙقدة الرسومات المتØركة لأجل الرسم graph." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Path to an AnimationPlayer node containing animations is not set." -msgstr "Øدد مشغل Øركة من شجرة المشهد لكي تعدل الØركة." +msgstr "لم يتم تØديد مسار ÙŠØتوي ارسومات المتØركة لعÙقدة Ù…Ùشغل الرسومات المتØركة." #: scene/animation/animation_tree.cpp msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" +"المسار المÙØدد لمÙشغل الرسومات المتØركة لا يقود إلى عÙقدة Ù…Ùشغل رسومات Ù…ÙتØركة." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "The AnimationPlayer root node is not a valid node." -msgstr "شجرة الØركة خاطئة." +msgstr "العÙقدة الرئيسة لمÙشغل الرسومات المتØركة ليست عÙقدة صالØØ©." #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." msgstr "" +"لقد تم إهمال هذه العÙقدةز استخدم شجرة الرسومات المتØركة AnimationTree بدلاً عن " +"ذلك." #: scene/gui/color_picker.cpp msgid "" @@ -12783,27 +12692,29 @@ msgid "" "LMB: Set color\n" "RMB: Remove preset" msgstr "" +"اللون: #%s\n" +"الزر الأيسر للÙأرة: تØديد اللون\n" +"الزر الأيمن للÙأرة: إزالة اللون الØالي" #: scene/gui/color_picker.cpp msgid "Pick a color from the editor window." -msgstr "" +msgstr "اختر لوناً من ناÙذة المÙØرر." #: scene/gui/color_picker.cpp msgid "HSV" -msgstr "" +msgstr "HSV" #: scene/gui/color_picker.cpp msgid "Raw" -msgstr "" +msgstr "خام" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." -msgstr "" +msgstr "بدّل بين القيم البرمجية والسداسية العشرية." #: scene/gui/color_picker.cpp -#, fuzzy msgid "Add current color as a preset." -msgstr "أض٠اللون الØالي كإعداد مسبق" +msgstr "أض٠اللون الØالي كإعداد مسبق." #: scene/gui/container.cpp msgid "" @@ -12824,7 +12735,7 @@ msgstr "تنبيه!" #: scene/gui/dialogs.cpp msgid "Please Confirm..." -msgstr "يرجى التاكيد..." +msgstr "ÙŠÙرجى التأكيد..." #: scene/gui/popup.cpp msgid "" @@ -12846,7 +12757,7 @@ msgstr "" #: scene/gui/tree.cpp msgid "(Other)" -msgstr "" +msgstr "(أخرى)" #: scene/main/scene_tree.cpp msgid "" @@ -12864,7 +12775,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "ينبغي أن يكون Øجم إطار العرض أكبر من 0 ليتم الإخراج البصري لأي شيء." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." @@ -12876,11 +12787,11 @@ msgstr "مصدر غير ØµØ§Ù„Ø Ù„ØªØ¸Ù„ÙŠÙ„." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid comparison function for that type." -msgstr "comparison function غير صالØØ© لهذا النوع." +msgstr "وظيÙØ© برمجية Ù…ÙقارÙنة غير صالØØ© لأجل ذلك النوع." #: servers/visual/shader_language.cpp msgid "Assignment to function." -msgstr "التعيين لتعمل." +msgstr "تكليÙها لوظيÙØ© برمجية." #: servers/visual/shader_language.cpp msgid "Assignment to uniform." diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 1dcaf7fa32..c9be0c2c3f 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -8,7 +8,6 @@ # MaresPW <marespw206@gmail.com>, 2018. # PakoSt <kokotekilata@gmail.com>, 2018, 2020. # Damyan Dichev <mwshock2@gmail.com>, 2019. -# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" @@ -9684,6 +9683,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10796,6 +10802,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "ИзнаÑÑне на профила" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index b37267652e..3f5c140428 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -10559,6 +10559,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "কী/চাবি " @@ -11764,6 +11771,11 @@ msgid "Total:" msgstr "সরà§à¦¬à¦®à§‹à¦Ÿ:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "পà§à¦°à¦•à¦²à§à¦ª à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "রিসোরà§à¦¸-à¦à¦° পথ" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 21886cea24..a1577b5a15 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -10189,6 +10189,13 @@ msgstr "" "Actualment no teniu cap projecte.\n" "Us agradaria explorar projectes d'exemple oficials a la biblioteca d'actius?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Tecla " @@ -11351,6 +11358,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportar Perfil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Camà de Recursos" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 887bbeb8f4..566ff0c1e2 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -9916,6 +9916,13 @@ msgstr "" "V této chvÃli nemáte žádný projekt.\n" "PÅ™ejete si prozkoumat oficiálnà ukázkové projekty v knihovnÄ› assetů?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Klávesa " @@ -11035,6 +11042,11 @@ msgid "Total:" msgstr "Celkem:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportovat profil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Cesta ke zdroji" diff --git a/editor/translations/da.po b/editor/translations/da.po index e582e4f3f9..5e88313d95 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -10149,6 +10149,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11303,6 +11310,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Eksporter Projekt" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/de.po b/editor/translations/de.po index dc12e814b0..86e7d09671 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -53,8 +53,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-14 15:05+0000\n" -"Last-Translator: So Wieso <sowieso@dukun.de>\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" +"Last-Translator: anonymous <noreply@weblate.org>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" "Language: de\n" @@ -62,7 +62,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2992,13 +2992,12 @@ msgid "Q&A" msgstr "Fragen & Antworten" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Neuimport" +msgstr "Fehler berichten" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Dokumentationsvorschläge senden" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4056,7 +4055,6 @@ msgid "Reimport" msgstr "Neuimport" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Szenen speichern, reimportieren und neu starten" @@ -7365,9 +7363,8 @@ msgid "This operation requires a single selected node." msgstr "Diese Aktion benötigt einen einzelnen ausgewählten Node." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Orthogonal" +msgstr "Auto-Orthogonal aktiviert" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9999,6 +9996,13 @@ msgstr "" "Sollen offizielle Beispielprojekte aus der Nutzerinhaltesammlung angezeigt " "werden?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Taste " @@ -10751,7 +10755,7 @@ msgstr "Node unter neues Node hängen" #: editor/scene_tree_dock.cpp msgid "Make Scene Root" -msgstr "Szenen-Wurzel erstellen" +msgstr "Als Szenen-Wurzel festlegen" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -10995,6 +10999,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Hinweis: Eingebettete Skripte unterliegen gewissen Einschränkungen und " +"können nicht mit einem externen Editor bearbeitet werden." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11117,6 +11123,11 @@ msgid "Total:" msgstr "Insgesamt:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Profil exportieren" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Ressourcenpfad" @@ -12808,6 +12819,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"Die Größe des Viewports muss größer als 0 sein um etwas rendern zu können." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po index e17231a0dd..c86daa54dc 100644 --- a/editor/translations/de_CH.po +++ b/editor/translations/de_CH.po @@ -4,7 +4,6 @@ # This file is distributed under the same license as the Godot source code. # Christian Fisch <christian.fiesel@gmail.com>, 2016. # Nils <nfa106008@iet-gibb.ch>, 2020. -# anonymous <noreply@weblate.org>, 2020. # PagDev <pag.develop@gmail.com>, 2020. msgid "" msgstr "" @@ -9969,6 +9968,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Taste " @@ -11099,6 +11105,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Projekt exportieren" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 466aa8fa7f..1302e33e47 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -9501,6 +9501,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10582,6 +10589,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index 2c8335393b..b01976c477 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-23 03:47+0000\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" "Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" @@ -20,7 +20,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2951,13 +2951,12 @@ msgid "Q&A" msgstr "ΕÏωτήσεις & Απαντήσεις" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Επανεισαγωγή" +msgstr "ΑναφοÏά Σφάλματος" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Αποστολή Σχολίων ΤεκμηÏίωσης" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4018,9 +4017,8 @@ msgid "Reimport" msgstr "Επανεισαγωγή" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Αποθήκευση σκηνών, επανεισαγωγή και επανεκκίνηση" +msgstr "Αποθήκευση Σκηνών, Επανεισαγωγή και Επανεκκίνηση" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -7334,9 +7332,8 @@ msgid "This operation requires a single selected node." msgstr "Αυτή η λειτουÏγία απαιτεί Îναν μόνο επιλεγμÎνο κόμβο." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "ΑξονομετÏική" +msgstr "Αυτόματη ΑξονομετÏική ΕνεÏγή" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9958,6 +9955,13 @@ msgstr "" "Δεν Îχετε κανÎνα ÎÏγο.\n" "ΘÎλετε να εξεÏευνήσετε μεÏικά επίσημα παÏαδείγματα στην βιβλιοθήκη πόÏων;" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Κλειδί " @@ -10955,6 +10959,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Σημείωση: Οι ενσωματωμÎνες δÎσμες ενεÏγειών Îχουν πεÏιοÏισμοÏÏ‚ και δεν " +"μποÏοÏν να ανοιχτοÏν σε εξωτεÏικό επεξεÏγαστή." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11079,6 +11085,11 @@ msgid "Total:" msgstr "Συνολικά:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Εξαγωγή Î Ïοφίλ" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "ΔιαδÏομή πόÏου" @@ -12762,6 +12773,8 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"Το μÎγεθος της οπτικής γωνίας Ï€ÏÎπει να είναι μεγαλÏτεÏο του 0 για να γίνει " +"απόδοση." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 7dc152659f..dc10209d18 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -9647,6 +9647,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10737,6 +10744,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/es.po b/editor/translations/es.po index c9ca261498..933cff80a4 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -43,15 +43,14 @@ # Dario <darlex259@gmail.com>, 2019. # Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2019. # Julián Luini <jluini@gmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. # Victor S. <victorstancioiu@gmail.com>, 2020. # henry rujano herrera <rujhen@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-16 11:03+0000\n" -"Last-Translator: anonymous <noreply@weblate.org>\n" +"PO-Revision-Date: 2020-04-23 20:21+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" @@ -59,7 +58,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.0.1-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -642,7 +641,7 @@ msgstr "Usar Curvas Bezier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "Optimizador de Animación" +msgstr "Optimizar Animación" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" @@ -845,7 +844,7 @@ msgstr "Eliminar" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Añadir un Argumento de Llamada Extra:" +msgstr "Añadir Argumento de Llamada Extra:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" @@ -2994,13 +2993,12 @@ msgid "Q&A" msgstr "Preguntas y respuestas" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Reimportar" +msgstr "Reportar un Bug" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Enviar Feedback de la Documentación" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3012,7 +3010,7 @@ msgstr "Acerca de" #: editor/editor_node.cpp msgid "Play the project." -msgstr "Ejecutar el proyecto." +msgstr "Reproducir el proyecto." #: editor/editor_node.cpp msgid "Play" @@ -4060,9 +4058,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Guardar escenas, reimportar y reiniciar" +msgstr "Guardar Escenas, Reimportar y Reiniciar" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -5274,8 +5271,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" -"Cuando esté activo, moviendo los nodos de Control cambiará sus anclas en " -"lugar de sus márgenes." +"Cuando está activo, el movimiento de los nodos de Control cambian sus " +"anclajes en lugar de sus márgenes." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Top Left" @@ -7367,9 +7364,8 @@ msgid "This operation requires a single selected node." msgstr "Esta operación requiere un solo nodo seleccionado." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonal" +msgstr "Auto Ortogonal Activado" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9995,6 +9991,13 @@ msgstr "" "Actualmente no tienes ningún proyecto.\n" "¿Quieres explorar proyectos de ejemplo oficiales en la Biblioteca de Assets?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Tecla " @@ -10988,6 +10991,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Nota: Los scripts integrados tienen algunas limitaciones y no pueden ser " +"editados usando un editor externo." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11110,6 +11115,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportar Perfil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Ruta de Recursos" @@ -11443,7 +11453,7 @@ msgstr "Eliminar Rotación del Cursor" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Paste Selects" -msgstr "Pegar Selecciona" +msgstr "Pegar Seleccionados" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" @@ -12801,6 +12811,8 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"El tamaño del Viewport debe ser mayor que 0 para poder renderizar cualquier " +"cosa." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 7e7ed33aca..bd6d934a59 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-11 12:20+0000\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -27,7 +27,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -8390,7 +8390,7 @@ msgstr "Crear PolÃgono Cóncavo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Convex" -msgstr "Crear PolÃgono Convexo" +msgstr "Hacer el PolÃgono Convexo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Tile" @@ -9950,6 +9950,13 @@ msgstr "" "Actualmente no tenés ningún proyecto.\n" "¿Te gustarÃa explorar los ejemplos oficiales en la Biblioteca de Assets?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Tecla " @@ -11066,6 +11073,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportar Perfil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Ruta de Recursos" diff --git a/editor/translations/et.po b/editor/translations/et.po index 6c052803e0..2ed8f83317 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -9524,6 +9524,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10608,6 +10615,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index 49fb37e599..f633f1c298 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -9506,6 +9506,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10587,6 +10594,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index f45393c505..2754720d3b 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -11,15 +11,14 @@ # Behrooz Kashani <bkashani@gmail.com>, 2018. # Mahdi <sadisticwarlock@gmail.com>, 2018. # hpn33 <hamed.hpn332@gmail.com>, 2019, 2020. -# Focus <saeeddashticlash@gmail.com>, 2019. -# anonymous <noreply@weblate.org>, 2020. +# Focus <saeeddashticlash@gmail.com>, 2019, 2020. # mohamad por <mohamad24xx@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-09 07:52+0000\n" -"Last-Translator: hpn33 <hamed.hpn332@gmail.com>\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" +"Last-Translator: Focus <saeeddashticlash@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" "Language: fa\n" @@ -27,7 +26,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1257,7 +1256,7 @@ msgstr "" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "" +msgstr "موÙقیت!" #: editor/editor_asset_installer.cpp #, fuzzy @@ -1352,7 +1351,7 @@ msgstr "Øذ٠اثر" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "" +msgstr "صدا" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -2905,6 +2904,7 @@ msgid "" msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp +#, fuzzy msgid "Editor" msgstr "ویرایشگر" @@ -4641,7 +4641,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "انیمیشن" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -10102,6 +10102,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10428,7 +10435,7 @@ msgstr "بارگیری خودکار" #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "" +msgstr "پلاگین ها" #: editor/property_editor.cpp msgid "Preset..." @@ -11260,6 +11267,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "صدور پروژه" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 74bc461021..af9486a2ad 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-14 15:05+0000\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -23,7 +23,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2921,13 +2921,12 @@ msgid "Q&A" msgstr "Kysymykset ja vastaukset" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Tuo uudelleen" +msgstr "Raportoi bugi" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Lähetä palautetta ohjeesta" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3981,7 +3980,6 @@ msgid "Reimport" msgstr "Tuo uudelleen" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Tallenna skenet, tuo uudelleen ja käynnistä uudelleen" @@ -5543,7 +5541,7 @@ msgstr "Näytä origo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Viewport" -msgstr "Näytä näyttöikkuna" +msgstr "Näytä näyttöruutu" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" @@ -7277,9 +7275,8 @@ msgid "This operation requires a single selected node." msgstr "Tämä toiminto vaatii yhden valitun solmun." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonaalinen" +msgstr "Automaattinen ortogonaalinen päällä" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9895,6 +9892,13 @@ msgstr "" "Sinulla ei ole tällä hetkellä yhtään projekteja.\n" "Haluaisitko selata virallisia esimerkkiprojekteja Asset-kirjastosta?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Näppäin " @@ -10889,6 +10893,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Huom: sisäänrakennetuilla skripteillä on joitakin rajoituksia, eikä niitä " +"voi muokata ulkoisella editorilla." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11011,6 +11017,11 @@ msgid "Total:" msgstr "Yhteensä:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Vie profiili" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Resurssipolku" @@ -12673,6 +12684,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"Näyttöruudun koko on oltava suurempi kuin 0, jotta mitään renderöidään." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 5a1942fee5..32405930ea 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -9525,6 +9525,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10607,6 +10614,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 0844df8dc7..552da2cedf 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -71,13 +71,13 @@ # Pierre Stempin <pierre.stempin@gmail.com>, 2019. # Pierre Caye <pierrecaye@laposte.net>, 2020. # Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. +# LaurentOngaro <laurent@gameamea.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-03 09:09+0000\n" -"Last-Translator: anonymous <noreply@weblate.org>\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" +"Last-Translator: LaurentOngaro <laurent@gameamea.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -85,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -105,11 +105,11 @@ msgstr "Pas assez d'octets pour le décodage, ou format non valide." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "Entrée non valide %i (pas passée) dans l’expression" +msgstr "Entrée non valide %i (non transmise) dans l’expression" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "self ne peut être utilisé car l'instance est null (pas passée)" +msgstr "self ne peut être utilisé car l'instance est nulle (non passée)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -2230,7 +2230,7 @@ msgstr "Nouvelle Fenêtre" #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "Les ressources importés ne peuvent pas être sauvegarder." +msgstr "Les ressources importées ne peuvent pas être sauvegardées." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -3024,13 +3024,12 @@ msgid "Q&A" msgstr "Questions et réponses" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Réimporter" +msgstr "Signaler un bug" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Envoyez vos retours sur la documentation" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4092,9 +4091,8 @@ msgid "Reimport" msgstr "Réimporter" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Sauvegarde des scènes, réimportation et redémarrage" +msgstr "Sauvegarder les scènes, Réimporter, et Redémarrer" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -6857,7 +6855,7 @@ msgstr "Basculer le tri alphabétique de la liste de méthodes." #: editor/plugins/script_editor_plugin.cpp msgid "Filter methods" -msgstr "Méthodes de filtrage" +msgstr "Filtrer les méthodes" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" @@ -7413,9 +7411,8 @@ msgstr "" "sélectionné." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Orthogonale" +msgstr "Auto Orthogonal Activé" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9699,7 +9696,7 @@ msgstr "Fichier ZIP" #: editor/project_export.cpp msgid "Godot Game Pack" -msgstr "Données de jeu Godot" +msgstr "Archive Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" @@ -10051,6 +10048,17 @@ msgstr "" "Vous n'avez pour l'instant aucun projets.\n" "Voulez-vous explorer des exemples de projets officiels dans l'Asset Library ?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" +"La barre de recherche filtre les projets par leur nom et la dernière partie " +"de leur chemin d'accès.\n" +"Pour filter les projects par leur nom et le chemin d'accès complet, la " +"recherche doit inclure au moins un caractère `/`." + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Touche " @@ -10253,19 +10261,19 @@ msgstr "Ajouter un chemin remappé" #: editor/project_settings_editor.cpp msgid "Resource Remap Add Remap" -msgstr "Réaffectation des ressources ; Ajouter une réaffectation" +msgstr "Réaffectation (remap) des ressources ; Ajouter une réaffectation" #: editor/project_settings_editor.cpp msgid "Change Resource Remap Language" -msgstr "Modifier le langage de réaffectation des ressources" +msgstr "Modifier le langage de réaffectation (remap) des ressources" #: editor/project_settings_editor.cpp msgid "Remove Resource Remap" -msgstr "Supprimer la réaffectation des ressources" +msgstr "Supprimer la réaffectation (remap) des ressources" #: editor/project_settings_editor.cpp msgid "Remove Resource Remap Option" -msgstr "Supprimer option de remap de ressource" +msgstr "Supprimer l'option de réaffectation (remap) de ressource" #: editor/project_settings_editor.cpp msgid "Changed Locale Filter" @@ -10273,7 +10281,7 @@ msgstr "Filtre de langue modifié" #: editor/project_settings_editor.cpp msgid "Changed Locale Filter Mode" -msgstr "Changé le mode de filtrage des langues" +msgstr "Mode de filtrage des langues modifié" #: editor/project_settings_editor.cpp msgid "Project Settings (project.godot)" @@ -10285,7 +10293,7 @@ msgstr "Général" #: editor/project_settings_editor.cpp msgid "Override For..." -msgstr "Écraser pour…" +msgstr "Surcharge pour…" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "The editor must be restarted for changes to take effect." @@ -10329,7 +10337,7 @@ msgstr "Traductions :" #: editor/project_settings_editor.cpp msgid "Remaps" -msgstr "Remaps" +msgstr "Réaffectation" #: editor/project_settings_editor.cpp msgid "Resources:" @@ -10337,7 +10345,7 @@ msgstr "Ressources :" #: editor/project_settings_editor.cpp msgid "Remaps by Locale:" -msgstr "Remaps par langue :" +msgstr "Réaffectations (remaps) par langue :" #: editor/project_settings_editor.cpp msgid "Locale" @@ -11043,6 +11051,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Remarque : les scripts intégrés ont certaines limitations et ne peuvent pas " +"être modifiés à l'aide d'un éditeur externe." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11166,6 +11176,10 @@ msgid "Total:" msgstr "Total :" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "Exporter la liste en fichier CSV" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Chemin de la ressource" @@ -12867,6 +12881,8 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"La taille de la fenêtre d'affichage doit être supérieure à 0 pour pouvoir " +"afficher quoi que ce soit." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ga.po b/editor/translations/ga.po index d40b50cd90..7b271f6a77 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -9520,6 +9520,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10603,6 +10610,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index 1a82804b31..35421252b2 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -10077,6 +10077,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "מקש " @@ -11225,6 +11232,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "×™×™×¦×•× ×ž×™×–×" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 75f29b8e0b..12cf8fd242 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -10,14 +10,13 @@ # Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019. # Devashishsingh98 <devashishsingh98@gmail.com>, 2019. # Shirious <sad3119823@gmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. # Abhay Patel <Traumaticbean@protonmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-03 09:50+0000\n" -"Last-Translator: Suryansh5545 <suryanshpathak5545@gmail.com>\n" +"PO-Revision-Date: 2020-04-24 06:48+0000\n" +"Last-Translator: Shirious <sad3119823@gmail.com>\n" "Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/" "hi/>\n" "Language: hi\n" @@ -25,7 +24,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2332,9 +2331,8 @@ msgid "Open Base Scene" msgstr "ओपन बेस सीन" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "खोलो इसे" +msgstr "तà¥à¤°à¤‚त खोलिये..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2457,9 +2455,8 @@ msgid "Close Scene" msgstr "कà¥à¤²à¥‹à¤œ सीन" #: editor/editor_node.cpp -#, fuzzy msgid "Reopen Closed Scene" -msgstr "खोलो इसे" +msgstr "बंद सीन फिर से खोलें" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." @@ -2564,14 +2561,12 @@ msgid "Play This Scene" msgstr "इस दृशà¥à¤¯ को खेलो" #: editor/editor_node.cpp -#, fuzzy msgid "Close Tab" -msgstr "बंद करे" +msgstr "टैब बंद करे" #: editor/editor_node.cpp -#, fuzzy msgid "Undo Close Tab" -msgstr "बंद करे" +msgstr "बंद टैब अनकिया करें" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" @@ -2582,9 +2577,8 @@ msgid "Close Tabs to the Right" msgstr "टैब को दाईं ओर बंद करें" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "बंद करे" +msgstr "सà¤à¥€ टैब बंद करे" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2627,9 +2621,8 @@ msgid "Go to previously opened scene." msgstr "पहले खोले गठदृशà¥à¤¯ में जाà¤à¤‚।" #: editor/editor_node.cpp -#, fuzzy msgid "Copy Text" -msgstr "सà¤à¥€ खंड" +msgstr "टेकà¥à¤¸à¥à¤Ÿ कौपी कीजिये" #: editor/editor_node.cpp msgid "Next tab" @@ -2731,18 +2724,16 @@ msgid "Install Android Build Template..." msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..." #: editor/editor_node.cpp -#, fuzzy msgid "Open Project Data Folder" -msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•" +msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डेटा फ़ोलà¥à¤¡à¤° खोलिये" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" msgstr "उपकरण" #: editor/editor_node.cpp -#, fuzzy msgid "Orphan Resource Explorer..." -msgstr "Orphan Resource Explorer" +msgstr "असहाय रेसोरà¥à¤¸ खोजकरà¥à¤¤à¤¾..." #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2842,9 +2833,8 @@ msgid "Editor" msgstr "संपादक" #: editor/editor_node.cpp -#, fuzzy msgid "Editor Settings..." -msgstr "अनà¥à¤µà¤¾à¤¦ में बदलाव करें:" +msgstr "à¤à¤¡à¥€à¤Ÿà¤° सेटिनà¥à¤—स..." #: editor/editor_node.cpp msgid "Editor Layout" @@ -2910,11 +2900,11 @@ msgstr "Q&A" #: editor/editor_node.cpp msgid "Report a Bug" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® में तà¥à¤°à¥à¤Ÿà¤¿ की शिकायत करें" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Docs की पà¥à¤°à¤¤à¤¿à¤•à¥à¤°à¤¿à¤¯à¤¾ à¤à¥‡à¤œà¥‡à¤‚" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3103,9 +3093,8 @@ msgid "Warning!" msgstr "चेतावनी!" #: editor/editor_path.cpp -#, fuzzy msgid "No sub-resources found." -msgstr "संसाधन" +msgstr "सब-रिसोरà¥à¤¸ नहीं मिला." #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" @@ -3116,9 +3105,8 @@ msgid "Thumbnail..." msgstr "थंबनेल..." #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Main Script:" -msgstr "निरà¥à¤à¤°à¤¤à¤¾ संपादक" +msgstr "मेन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ:" #: editor/editor_plugin_settings.cpp msgid "Edit Plugin" @@ -3190,9 +3178,8 @@ msgid "Calls" msgstr "कॉल" #: editor/editor_properties.cpp -#, fuzzy msgid "Edit Text:" -msgstr "परिवरà¥à¤¤à¤¨ वकà¥à¤° चयन" +msgstr "टेकà¥à¤¸à¥à¤Ÿ संपादित करें:" #: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" @@ -3215,9 +3202,8 @@ msgid "Assign..." msgstr "सौंपना..." #: editor/editor_properties.cpp -#, fuzzy msgid "Invalid RID" -msgstr "गलत फॉणà¥à¤Ÿ का आकार |" +msgstr "अमानà¥à¤¯ RID" #: editor/editor_properties.cpp msgid "" @@ -3469,9 +3455,8 @@ msgid "Download Complete." msgstr "पूरा डाउनलोड करें।" #: editor/export_template_manager.cpp -#, fuzzy msgid "Cannot remove temporary file:" -msgstr "निकाला नहीं जा सकता:" +msgstr "अलà¥à¤ªà¤•à¤¾à¤²à¤¿à¤• फ़ाइल निकाली नहीं जा सकà¥à¤¤à¥€:" #: editor/export_template_manager.cpp msgid "" @@ -3610,19 +3595,19 @@ msgstr "बशरà¥à¤¤à¥‡ नाम में अमानà¥à¤¯ पातà¥à¤ #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "इस नाम से फ़ाइल या फ़ोलà¥à¤¡à¤° पहले से मौजूद." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "नाम मे अमानà¥à¤¯ अकà¥à¤·à¤° मौजूद." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "" +msgstr "फ़ाइल का नाम बदल रहे है:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "फ़ोलà¥à¤¡à¤° का नाम बदल रहे है:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" @@ -3634,11 +3619,11 @@ msgstr "डà¥à¤ªà¥à¤²à¤¿à¤•à¥‡à¤Ÿà¤¿à¤‚ग फ़ोलà¥à¤¡à¤°:" #: editor/filesystem_dock.cpp msgid "New Inherited Scene" -msgstr "" +msgstr "नई उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•à¤¾à¤° पà¥à¤°à¤¾à¤ªà¥à¤¤ सीन" #: editor/filesystem_dock.cpp msgid "Set As Main Scene" -msgstr "" +msgstr "मेन सीन सेट करे" #: editor/filesystem_dock.cpp msgid "Open Scenes" @@ -3658,7 +3643,7 @@ msgstr "पसंदीदा से निकालें" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "" +msgstr "निरà¥à¤à¤°à¤¿à¤¤ फ़ाइलें संपादित करें..." #: editor/filesystem_dock.cpp msgid "View Owners..." @@ -9730,6 +9715,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10833,6 +10825,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 5087044b13..8627e7f239 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -9567,6 +9567,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10656,6 +10663,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 54206db36f..d066d5e317 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -10265,6 +10265,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11409,6 +11416,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Projekt Exportálása" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/id.po b/editor/translations/id.po index 087a274249..54222d1aeb 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -9925,6 +9925,13 @@ msgstr "" "Saat ini Anda tidak memiliki proyek.\n" "Apakah Anda ingin menjelajahi contoh proyek resmi di Pustaka Aset?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Kunci " @@ -11041,6 +11048,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Ekspor Profil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Lokasi Resource" diff --git a/editor/translations/is.po b/editor/translations/is.po index bb865e255a..e2943eb9cf 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -9629,6 +9629,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10716,6 +10723,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index 4ce247c712..1c7c72ce12 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -45,12 +45,13 @@ # Fabio Iotti <fabiogiopla@gmail.com>, 2020. # Douglas Fiedler <dognew@gmail.com>, 2020. # E440QF <ettore.beltra@gmail.com>, 2020. +# Giuseppe Lucido <giuseppe.lucido@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-08 16:36+0000\n" -"Last-Translator: E440QF <ettore.beltra@gmail.com>\n" +"PO-Revision-Date: 2020-04-27 08:25+0000\n" +"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -58,7 +59,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2984,13 +2985,12 @@ msgid "Q&A" msgstr "Domande e risposte" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Reimporta" +msgstr "Riporta un Bug" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Invia opinione sui documenti" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4049,9 +4049,8 @@ msgid "Reimport" msgstr "Reimporta" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Salva scene, importa nuovamente e riavvia" +msgstr "Salva scene, re-importa e riavvia" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -6030,7 +6029,6 @@ msgstr "" "collisioni." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Crea Singolo Fratello di Collisione Convessa" @@ -7360,9 +7358,8 @@ msgid "This operation requires a single selected node." msgstr "Questa operazione richiede un solo nodo selezionato." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonale" +msgstr "Ortogonale Automatico Abilitato" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9991,6 +9988,13 @@ msgstr "" "Al momento non hai nessun progetto.\n" "Ti piacerebbe esplorare gli esempi ufficiali nella libreria degli Asset?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Tasto " @@ -10983,6 +10987,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Note: Gli script pre-installati hanno alcune limitazioni e non possono " +"essere modificati utilizzando un editor esterno." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11105,6 +11111,11 @@ msgid "Total:" msgstr "Totale:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Esporta profilo" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Percorso Risorsa" @@ -12788,6 +12799,8 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"La dimensione del Viewport deve essere maggiore di 0 affinché qualcosa sia " +"visibile." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index ab503d8294..aac20e9666 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -7,7 +7,7 @@ # Daisuke Saito <d.saito@coriginate.com>, 2017, 2018. # h416 <shinichiro.hirama@gmail.com>, 2017. # hopping tappy (ãŸã£ã´ã•ã‚“) <hopping.tappy@gmail.com>, 2016-2017, 2018. -# Jun Shiozawa <haresecret@gmail.com>, 2017, 2018. +# Jun Shiozawa <haresecret@gmail.com>, 2017, 2018, 2020. # Lexi Grafen <shfeedly@gmail.com>, 2017. # NoahDigital <taku_58@hotmail.com>, 2017. # Shinsuke Masuda <shinsuke.masuda@gmail.com>, 2018. @@ -35,8 +35,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-15 14:29+0000\n" -"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n" +"PO-Revision-Date: 2020-04-27 08:25+0000\n" +"Last-Translator: Anonymous <noreply@weblate.org>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\n" @@ -44,7 +44,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -297,7 +297,7 @@ msgstr "時間 (秒): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "トラックを有効ã«ã™ã‚‹" +msgstr "トラックを有効 / 無効" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -1210,7 +1210,7 @@ msgstr "コンãƒãƒ¼ãƒãƒ³ãƒˆ" #: editor/editor_about.cpp msgid "Licenses" -msgstr "ライセンス" +msgstr "ライセンス文書" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Error opening package file, not in ZIP format." @@ -1251,7 +1251,7 @@ msgstr "インストール" #: editor/editor_asset_installer.cpp msgid "Package Installer" -msgstr "パッケージインストーラー" +msgstr "パッケージインストーラ" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -1271,15 +1271,15 @@ msgstr "オーディオãƒã‚¹ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ を変更" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "オーディオãƒã‚¹ã®ã‚½ãƒã‚’切り替ãˆ" +msgstr "オーディオãƒã‚¹ã®ã‚½ãƒã‚’オン / オフ" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "オーディオãƒã‚¹ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’切り替ãˆ" +msgstr "オーディオãƒã‚¹ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’オン / オフ" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "オーディオãƒã‚¹ã®ãƒã‚¤ãƒ‘スエフェクトを切り替ãˆ" +msgstr "オーディオãƒã‚¹ã®ãƒã‚¤ãƒ‘スエフェクトをオン / オフ" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" @@ -1287,7 +1287,7 @@ msgstr "オーディオãƒã‚¹ã®å‡ºåŠ›å…ˆã‚’é¸æŠž" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" -msgstr "オーディオãƒã‚¹ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã‚’è¿½åŠ " +msgstr "オーディオãƒã‚¹ ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã‚’è¿½åŠ " #: editor/editor_audio_buses.cpp msgid "Move Bus Effect" @@ -1458,7 +1458,7 @@ msgstr "自動èªè¾¼ã¿ã®åå‰å¤‰æ›´" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "ã‚°ãƒãƒ¼ãƒãƒ«ã®è‡ªå‹•èªè¾¼ã¿ã‚’切り替ãˆ" +msgstr "ã‚°ãƒãƒ¼ãƒãƒ«ã®è‡ªå‹•èªè¾¼ã¿ã‚’オン / オフ" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" @@ -1858,11 +1858,11 @@ msgstr "上ã¸" #: editor/editor_file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "éš ã—ファイルã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "éš ã—ファイルをオン / オフ" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "ãŠæ°—ã«å…¥ã‚Šã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "ãŠæ°—ã«å…¥ã‚Šã®ã‚ªãƒ³ / オフ" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" @@ -1902,7 +1902,7 @@ msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’ãŠæ°—ã«å…¥ã‚Šã«ã™ã‚‹/ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å¤ #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle the visibility of hidden files." -msgstr "éš ã—ファイルã®è¡¨ç¤º/éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚" +msgstr "éš ã—ファイルã®è¡¨ç¤º / éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -2902,11 +2902,11 @@ msgstr "スクリーンショットã¯Editor Data / Settingsフォルダã«ä¿å #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "フルスクリーン切り替ãˆ" +msgstr "フルスクリーンã®æœ‰åŠ¹åŒ– / 無効化" #: editor/editor_node.cpp msgid "Toggle System Console" -msgstr "システムコンソールã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "システムコンソールã®æœ‰åŠ¹åŒ– / 無効化" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" @@ -2951,13 +2951,12 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ" +msgstr "ãƒã‚°ã‚’å ±å‘Š" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "ドã‚ュメントã®ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã‚’é€ã‚‹" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4008,9 +4007,8 @@ msgid "Reimport" msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "シーンをä¿å˜ã—ã¦ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•ã—ã¦ãã ã•ã„" +msgstr "シーンをä¿å˜ã—ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦ã‹ã‚‰ã€å†èµ·å‹•ã—ã¾ã™" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -4309,7 +4307,7 @@ msgstr "三角形ãŒå˜åœ¨ã—ãªã„ãŸã‚ã€ãƒ–レンドã§ãã¾ã›ã‚“。" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Toggle Auto Triangles" -msgstr "三角形ã®è‡ªå‹•ä½œæˆã«åˆ‡ã‚Šæ›¿ãˆ" +msgstr "三角形ã®è‡ªå‹•ä½œæˆã‚’オン / オフ" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create triangles by connecting points." @@ -4437,7 +4435,7 @@ msgstr "フィルタリングを有効化" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "自動å†ç”Ÿã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "自動å†ç”Ÿã®æœ‰åŠ¹åŒ– / 無効化" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" @@ -4723,8 +4721,8 @@ msgstr "é¸æŠžã—ãŸãƒŽãƒ¼ãƒ‰ã¾ãŸã¯ãƒˆãƒ©ãƒ³ã‚¸ã‚·ãƒ§ãƒ³ã‚’除去。" #: editor/plugins/animation_state_machine_editor.cpp msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" -"ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†ç”Ÿã®é–‹å§‹ã€å†èµ·å‹•ã€ã¾ãŸã¯ã‚¼ãƒã¸ã®ã‚·ãƒ¼ã‚¯ã‚’切り替ãˆã¾" -"ã™ã€‚" +"開始ã€å†ã‚¹ã‚¿ãƒ¼ãƒˆã€ã¾ãŸã¯ã‚¼ãƒã¸ã®ã‚·ãƒ¼ã‚¯æ™‚ã«ãŠã‘ã‚‹ã€ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†" +"生をオン / オフã«ã—ã¾ã™ã€‚" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set the end animation. This is useful for sub-transitions." @@ -5378,7 +5376,7 @@ msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag: Rotate" -msgstr "ドラッグ:回転" +msgstr "ドラッグ: 回転" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move" @@ -5432,7 +5430,7 @@ msgstr "定è¦ãƒ¢ãƒ¼ãƒ‰" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggle smart snapping." -msgstr "スマートスナッピングを切り替ãˆã‚‹ã€‚" +msgstr "スマート スナッピングをオン / オフ。" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Smart Snap" @@ -5440,7 +5438,7 @@ msgstr "スマートスナップを使ã†" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggle grid snapping." -msgstr "グリッドスナッピングを切り替ãˆã‚‹ã€‚" +msgstr "グリッド スナッピングをオン / オフ。" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Grid Snap" @@ -5693,7 +5691,7 @@ msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’è¨å®šã™ã‚‹" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Load Emission Mask" -msgstr "発光(Emission)マスクをèªã¿è¾¼ã‚€" +msgstr "放射マスクをèªã¿è¾¼ã‚€" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/cpu_particles_editor_plugin.cpp @@ -6272,7 +6270,7 @@ msgstr "曲線を分割ã™ã‚‹" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move Point in Curve" -msgstr "曲線内ã®ãƒã‚¤ãƒ³ãƒˆã‚’移動" +msgstr "曲線内ã®ç‚¹ã‚’移動" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move In-Control in Curve" @@ -7064,7 +7062,7 @@ msgstr "コンテã‚ストヘルプ" #: editor/plugins/script_text_editor.cpp msgid "Toggle Bookmark" -msgstr "ブックマークã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "ブックマークをã¤ã‘ã‚‹ / 外ã™" #: editor/plugins/script_text_editor.cpp msgid "Go to Next Bookmark" @@ -7089,7 +7087,7 @@ msgstr "è¡Œã«ç§»å‹•..." #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’切り替ãˆ" +msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’ã¤ã‘ã‚‹ / 外ã™" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" @@ -7296,9 +7294,8 @@ msgid "This operation requires a single selected node." msgstr "å˜ä¸€ã®é¸æŠžã•ã‚ŒãŸãƒŽãƒ¼ãƒ‰ãŒãªã„ã¨ã€ã“ã®æ“作ã¯è¡Œãˆã¾ã›ã‚“。" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "平行投影" +msgstr "自動平行投影 有効" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -7472,7 +7469,7 @@ msgstr "é¸æŠžã«ãƒ•ã‚©ãƒ¼ã‚«ã‚¹" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Freelook" -msgstr "フリールックã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "フリールックã®ã‚ªãƒ³ / オフ" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7594,7 +7591,7 @@ msgstr "ç„¡åã®ã‚®ã‚ºãƒ¢" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create Mesh2D" -msgstr "Mesh2Dを作æˆ" +msgstr "Mesh2Dを生æˆ" #: editor/plugins/sprite_editor_plugin.cpp msgid "Mesh2D Preview" @@ -7891,7 +7888,7 @@ msgstr "ç¾åœ¨ã®ã‚¨ãƒ‡ã‚£ã‚¿ãƒ†ãƒ¼ãƒžã‹ã‚‰ä½œæˆ" #: editor/plugins/theme_editor_plugin.cpp msgid "Toggle Button" -msgstr "ボタンã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "切り替ãˆãƒœã‚¿ãƒ³" #: editor/plugins/theme_editor_plugin.cpp msgid "Disabled Button" @@ -7971,7 +7968,7 @@ msgstr "サブツリー" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" -msgstr "ã‚ã‚Šã¾ã™ã‚ˆ,ãŸãã•ã‚“,オプション" +msgstr "Has,Many,Options" #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" @@ -9631,7 +9628,7 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã«åå‰ã‚’付ã‘ã¦ãã ã•ã„." #: editor/project_manager.cpp msgid "Invalid project path (changed anything?)." -msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スãŒç„¡åŠ¹ã§ã™(何ã‹ã‚’変更ã—ã¾ã—ãŸã‹?)。" +msgstr "無効ãªãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã§ã™ (ãªã«ã‹å¤‰æ›´ãŒã‚ã‚Šã¾ã—ãŸã‹ï¼Ÿ)。" #: editor/project_manager.cpp msgid "" @@ -9762,13 +9759,13 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"次ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯ã€ä½œæˆã«ä½¿ç”¨ã—ãŸGodotã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯æŒ‡å®šã•ã‚Œã¦" -"ã„ã¾ã›ã‚“。\n" +"次ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯ã€ä½œæˆã«ä½¿ç”¨ã•ã‚ŒãŸGodotã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•ã‚Œ" +"ã¦ã„ã¾ã›ã‚“。\n" "\n" "%s\n" "\n" "ファイルを開ãã¨ã€Godotã®ç¾åœ¨ã®è¨å®šãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ã«å¤‰æ›ã•ã‚Œã¾ã™ã€‚\n" -"è¦å‘Š:以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã§ã¯ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’é–‹ã‘ã¾ã›ã‚“。" +"è¦å‘Š: 以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã§ã¯ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã‚’é–‹ã‘ãªããªã‚Šã¾ã™ã€‚" #: editor/project_manager.cpp msgid "" @@ -9908,6 +9905,13 @@ msgstr "" "プãƒã‚¸ã‚§ã‚¯ãƒˆãŒä½•ã‚‚登録ã•ã‚Œã¦ã„ã¾ã›ã‚“。\n" "アセットライブラリã§å…¬å¼ã®ã‚µãƒ³ãƒ—ルプãƒã‚¸ã‚§ã‚¯ãƒˆã‚’ãƒã‚§ãƒƒã‚¯ã—ã¾ã™ã‹ï¼Ÿ" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "ã‚ー " @@ -10018,7 +10022,7 @@ msgstr "入力アクションを消去" #: editor/project_settings_editor.cpp msgid "Erase Input Action Event" -msgstr "入力アクションイベントを消去" +msgstr "入力アクション イベントを消去" #: editor/project_settings_editor.cpp msgid "Add Event" @@ -10026,7 +10030,7 @@ msgstr "ã‚¤ãƒ™ãƒ³ãƒˆã‚’è¿½åŠ " #: editor/project_settings_editor.cpp msgid "Button" -msgstr "\\ Button" +msgstr "Button" #: editor/project_settings_editor.cpp msgid "Left Button." @@ -10266,7 +10270,7 @@ msgstr "ファイルèªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: リソースã§ã¯ã‚ã‚Šã¾ã›ã‚“!" #: editor/property_editor.cpp msgid "Pick a Node" -msgstr "ノードをé¸æŠžã™ã‚‹" +msgstr "ノードをé¸ã¶" #: editor/property_editor.cpp msgid "Bit %d, val %d." @@ -10606,8 +10610,8 @@ msgid "" "Couldn't save new scene. Likely dependencies (instances) couldn't be " "satisfied." msgstr "" -"æ–°ã—ã„シーンをä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãä¾å˜é–¢ä¿‚(インスタンス)を満ãŸã™ã“" -"ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" +"æ–°ã—ã„シーンをä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãä¾å˜é–¢ä¿‚(インスタンス)を満ãŸã›ã¦" +"ã„ã¾ã›ã‚“。" #: editor/scene_tree_dock.cpp msgid "Error saving scene." @@ -10707,11 +10711,11 @@ msgstr "継承をクリアã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“!)" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" -msgstr "表示ã®åˆ‡ã‚Šæ›¿ãˆ" +msgstr "表示 / éžè¡¨ç¤ºã®åˆ‡ã‚Šæ›¿ãˆ" #: editor/scene_tree_editor.cpp msgid "Unlock Node" -msgstr "ノードã®ãƒãƒƒã‚¯è§£é™¤" +msgstr "ノードをãƒãƒƒã‚¯è§£é™¤" #: editor/scene_tree_editor.cpp msgid "Button Group" @@ -10839,7 +10843,7 @@ msgstr "エラー - ファイルシステムã«ã‚¹ã‚¯ãƒªãƒ—トを作æˆã§ãã¾ #: editor/script_create_dialog.cpp msgid "Error loading script from %s" -msgstr "%s ã‹ã‚‰ã®ã‚¹ã‚¯ãƒªãƒ—トã®èªã¿è¾¼ã¿ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" +msgstr "%s ã‹ã‚‰ã®ã‚¹ã‚¯ãƒªãƒ—トをèªã¿è¾¼ã¿ä¸ã«ã‚¨ãƒ©ãƒ¼" #: editor/script_create_dialog.cpp msgid "Overrides" @@ -10851,7 +10855,7 @@ msgstr "N/A" #: editor/script_create_dialog.cpp msgid "Open Script / Choose Location" -msgstr "スクリプトを開ã/å ´æ‰€ã‚’é¸æŠžã™ã‚‹" +msgstr "スクリプトを開ã / å ´æ‰€ã‚’é¸æŠžã™ã‚‹" #: editor/script_create_dialog.cpp msgid "Open Script" @@ -10867,7 +10871,7 @@ msgstr "無効ãªã‚¯ãƒ©ã‚¹å。" #: editor/script_create_dialog.cpp msgid "Invalid inherited parent name or path." -msgstr "継承ã•ã‚ŒãŸè¦ªã®åå‰ã¾ãŸã¯ãƒ‘スãŒç„¡åŠ¹ã§ã™ã€‚" +msgstr "継承ã™ã‚‹è¦ªã®åå‰ã€ã¾ãŸã¯ãƒ‘スãŒç„¡åŠ¹ã§ã™ã€‚" #: editor/script_create_dialog.cpp msgid "Script path/name is valid." @@ -10898,6 +10902,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"注: 組ã¿è¾¼ã¿ã‚¹ã‚¯ãƒªãƒ—トã«ã¯ã„ãã¤ã‹åˆ¶ç´„ãŒã‚ã‚Šã€ã¾ãŸå¤–部ã®ã‚¨ãƒ‡ã‚£ã‚¿ã§ã¯ç·¨é›†ã§ã" +"ã¾ã›ã‚“。" #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11020,6 +11026,11 @@ msgid "Total:" msgstr "åˆè¨ˆ:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "プãƒãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "リソースã®ãƒ‘ス(ResourcePath)" @@ -11061,11 +11072,11 @@ msgstr "数値データをCSVã¨ã—ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" -msgstr "ショートカットã®æ¶ˆåŽ»" +msgstr "ショートカットを消去" #: editor/settings_config_dialog.cpp msgid "Restore Shortcut" -msgstr "ショートカットã®å¾©å…ƒ" +msgstr "ショートカットを復元" #: editor/settings_config_dialog.cpp msgid "Change Shortcut" @@ -12192,8 +12203,8 @@ msgid "" "CPUParticles\" option for this purpose." msgstr "" "GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。\n" -"代ã‚ã‚Šã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert " -"to CPUParticles\" オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" +"代ã‚ã‚Šã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパー" +"ティクルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" @@ -12222,9 +12233,9 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" -"RigidBody2D(ã‚ャラクタモードã¾ãŸã¯ãƒªã‚¸ãƒƒãƒ‰ãƒ¢ãƒ¼ãƒ‰)ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚" -"ã«ç‰©ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•ã‚Œã¾ã™ã€‚\n" -"代ã‚ã‚Šã«ã€åã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。" +"RigidBody2D (Characterモードã¾ãŸã¯Rigidモード) ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚ã«" +"物ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ä¸Šæ›¸ãã•ã‚Œã¾ã™ã€‚\n" +"代ã‚ã‚Šã«ã€åã®ã‚³ãƒªã‚¸ãƒ§ãƒ³ シェイプã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。" #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -12429,8 +12440,8 @@ msgid "" "\" option for this purpose." msgstr "" "GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。\n" -"代ã‚ã‚Šã«CPUParticlesノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert to " -"CPUParticles\"オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" +"代ã‚ã‚Šã«CPUParticlesノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパーティ" +"クルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚" #: scene/3d/particles.cpp msgid "" @@ -12678,7 +12689,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "レンダーã™ã‚‹ã«ã¯ãƒ“ューãƒãƒ¼ãƒˆã®ã‚µã‚¤ã‚ºãŒ 0 より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚" #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ka.po b/editor/translations/ka.po index ad4d5072f6..07eeeb5377 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -9824,6 +9824,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10933,6 +10940,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index dd2d617eb8..b2dbd4e353 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -16,12 +16,13 @@ # Jiyoon Kim <kimjiy@dickinson.edu>, 2019. # Ervin <zetsmart@gmail.com>, 2019. # Tilto_ <tilto0822@develable.xyz>, 2020. +# Myeongjin Lee <aranet100@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-27 07:42+0000\n" -"Last-Translator: Tilto_ <tilto0822@develable.xyz>\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" +"Last-Translator: Myeongjin Lee <aranet100@gmail.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" "Language: ko\n" @@ -29,7 +30,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2924,13 +2925,12 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "다시 ê°€ì ¸ì˜¤ê¸°" +msgstr "버그 ë³´ê³ " #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "문서 피드백 보내기" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3976,7 +3976,6 @@ msgid "Reimport" msgstr "다시 ê°€ì ¸ì˜¤ê¸°" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "씬 ì €ìž¥, 다시 ê°€ì ¸ì˜¤ê¸° ë° ë‹¤ì‹œ 시작" @@ -7250,9 +7249,8 @@ msgid "This operation requires a single selected node." msgstr "ì´ ìž‘ì—…ì€ í•˜ë‚˜ì˜ ë…¸ë“œë¥¼ ì„ íƒí•´ì•¼ 합니다." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "ì§êµë³´ê¸°" +msgstr "ìžë™ ì§êµ 활성화" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9834,6 +9832,13 @@ msgstr "" "현재 프로ì 트가 í•˜ë‚˜ë„ ì—†ìŠµë‹ˆë‹¤.\n" "ì• ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ì—ì„œ ê³µì‹ ì˜ˆì œ 프로ì 트를 찾아볼까요?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "키 " @@ -10820,6 +10825,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"ì°¸ê³ : 내장 스í¬ë¦½íŠ¸ì—는 ì¼ë¶€ ì œí•œ 사í•ì´ 있으며 외부 편집기를 사용하여 편집" +"í• ìˆ˜ 없습니다." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -10942,6 +10949,11 @@ msgid "Total:" msgstr "ì „ì²´:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "프로필 내보내기" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "리소스 경로" @@ -12572,7 +12584,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "ë·°í¬íŠ¸ í¬ê¸°ëŠ” 무엇ì´ë“ ë Œë”ë§í•˜ê¸° 위해 0보다 커야 합니다." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 25cec6842f..57c377b571 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -9811,6 +9811,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10917,6 +10924,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Importuoti iÅ¡ Nodo:" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 973e732e2d..642050468b 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -9778,6 +9778,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10884,6 +10891,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/mi.po b/editor/translations/mi.po index f0b661e381..5c33f2e72e 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -9499,6 +9499,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10580,6 +10587,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 92ffb6f097..e46fd5a10d 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -9515,6 +9515,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10596,6 +10603,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index f368062a85..5b2a55ffbe 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -9506,6 +9506,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10587,6 +10594,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index dc18540ce3..09e2bcc096 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -9572,6 +9572,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10657,6 +10664,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 6ec911db7d..34d6e9dc76 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -10351,6 +10351,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11509,6 +11516,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Eksporter Prosjekt" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index d270e51f6f..ba11dc0dad 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -4,7 +4,7 @@ # This file is distributed under the same license as the Godot source code. # aelspire <aelspire@gmail.com>, 2017. # Aram Nap <xyphex.aram@gmail.com>, 2017. -# Arjan219 <arjannugteren1@gmail.com>, 2017-2018. +# Arjan219 <arjannugteren1@gmail.com>, 2017-2018, 2020. # Christophe Swolfs <swolfschristophe@gmail.com>, 2017. # Cornee Traas <corneetraas@hotmail.com>, 2017. # Daeran Wereld <daeran@gmail.com>, 2017. @@ -40,12 +40,11 @@ # Tirrin <lensenjoe@gmail.com>, 2019. # Filip Van Raemdonck <arrawn@gmail.com>, 2019. # Julian <jdhoogvorst@gmail.com>, 2019, 2020. -# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-15 14:29+0000\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" "Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -54,7 +53,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -69,7 +68,7 @@ msgstr "Tekenreeks met lengte 1 verwacht (één karakter)." #: 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 "Niet genoeg bytes om bytes te decoderen, of ongeldig formaat." +msgstr "Niet genoeg bytes om te decoderen, of ongeldig formaat." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -662,7 +661,7 @@ msgstr "Alle animaties opruimen" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Animatie(s) Opruimen (KAN NIET ONGEDAAN WORDEN!)" +msgstr "Animatie(s) opruimen (ONOMKEERBAAR!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" @@ -695,11 +694,11 @@ msgstr "Voeg audiospoor clip toe" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Wijzig start afwijking van audiospoorclip" +msgstr "Wijzig startverschuiving van audiospoorclip" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "Wijzig eind afwijking van audiospoorclip" +msgstr "Wijzig eindverschuiving van audiospoorclip" #: editor/array_property_edit.cpp msgid "Resize Array" @@ -723,7 +722,7 @@ msgstr "Regelnummer:" #: editor/code_editor.cpp msgid "%d replaced." -msgstr "%d vervangen." +msgstr "%d vervangingen." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." @@ -747,7 +746,7 @@ msgstr "Vervangen" #: editor/code_editor.cpp msgid "Replace All" -msgstr "Alle Vervangen" +msgstr "Alles vervangen" #: editor/code_editor.cpp msgid "Selection Only" @@ -1071,7 +1070,7 @@ msgid "" msgstr "" "De bestanden die verwijderd worden zijn nodig om andere bronnen te laten " "werken.\n" -"Toch verwijderen? (Kan niet ongedaan worden)" +"Toch verwijderen? (Onomkeerbaar)" #: editor/dependency_editor.cpp msgid "Cannot remove:" @@ -1103,7 +1102,7 @@ msgstr "Fouten bij het laden!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "%d bestand(en) voorgoed verwijderen? (Kan niet ongedaan worden!)" +msgstr "%d bestand(en) voorgoed verwijderen? (Onomkeerbaar!)" #: editor/dependency_editor.cpp msgid "Show Dependencies" @@ -1606,7 +1605,7 @@ msgid "" "'Import Etc 2' in Project Settings." msgstr "" "Doelplatform vereist 'ETC2' textuurcompressie voor GLES3. Schakel 'Import " -"Etc 2' in bij de Projectinstellingen." +"Etc 2' in de Projectinstellingen in." #: editor/editor_export.cpp msgid "" @@ -1670,7 +1669,7 @@ msgstr "Bestandssysteem- en Importtablad" #: editor/editor_feature_profile.cpp msgid "Erase profile '%s'? (no undo)" -msgstr "Profiel '%s' verwijderen? (kan niet ongedaan gemaakt worden)" +msgstr "Profiel '%s' verwijderen? (Onomkeerbaar)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" @@ -2387,7 +2386,7 @@ msgstr "Basisscène openen" #: editor/editor_node.cpp msgid "Quick Open..." -msgstr "Snel Openen..." +msgstr "Snel openen..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2395,7 +2394,7 @@ msgstr "Scène snel openen..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Open Script Snel..." +msgstr "Script snel openen..." #: editor/editor_node.cpp msgid "Save & Close" @@ -2464,7 +2463,8 @@ msgstr "Herstellen" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "Deze actie kan niet ongedaan gemaakt worden. Toch herstellen?" +msgstr "" +"Deze actie kan niet ongedaan gemaakt worden. WIlt u desondanks terugzetten?" #: editor/editor_node.cpp msgid "Quick Run Scene..." @@ -2743,7 +2743,7 @@ msgstr "TileSet..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Undo" -msgstr "Ongedaan Maken" +msgstr "Ongedaan maken" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -2797,7 +2797,7 @@ msgstr "Hulpmiddelen" #: editor/editor_node.cpp msgid "Orphan Resource Explorer..." -msgstr "Verweesde hulpbronnen verkenner..." +msgstr "Beheer ongebruikte bronnen..." #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2918,7 +2918,7 @@ msgstr "Schermafbeeldingen worden bewaard in de map \"Editor Data/Settings\"." #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "Schakel Volledig Scherm" +msgstr "Volledig scherm" #: editor/editor_node.cpp msgid "Toggle System Console" @@ -2967,13 +2967,12 @@ msgid "Q&A" msgstr "Vragen en antwoorden" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Opnieuw importeren" +msgstr "Meld een probleem" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Suggesties voor documentatie verzenden" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3683,7 +3682,7 @@ msgstr "Naam bevat ongeldige tekens." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "Bestandsnaam wijzigen:" +msgstr "Bestand hernoemen:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" @@ -3865,7 +3864,7 @@ msgstr "Vervangen: " #: editor/find_in_files.cpp msgid "Replace all (no undo)" -msgstr "Alle vervangen (geen ongedaan maken)" +msgstr "Alles vervangen (onomkeerbaar)" #: editor/find_in_files.cpp msgid "Searching..." @@ -4030,9 +4029,8 @@ msgid "Reimport" msgstr "Opnieuw importeren" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Opnieuw importeren en herstarten (alle scènes worden opgeslagen)" +msgstr "Sla scènes op, importeer opnieuw en start dan opnieuw op" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -4082,7 +4080,7 @@ msgstr "Integreer" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" -msgstr "Maak Onderliggende Bronnen Uniek" +msgstr "Onderliggende bronnen zelfstandig maken" #: editor/inspector_dock.cpp msgid "Open in Help" @@ -5892,7 +5890,7 @@ msgstr "Mesh is leeg!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a Trimesh collision shape." -msgstr "Kon geen Trimesh-botsingsvorm maken." +msgstr "Kan geen Trimesh-botsingsvorm maken." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" @@ -7328,9 +7326,8 @@ msgid "This operation requires a single selected node." msgstr "Deze bewerking vereist één geselecteerde knoop." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Orthogonaal" +msgstr "Auto-orthogonaal ingeschakeld" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -7583,7 +7580,7 @@ msgstr "Beeldvensterinstellingen" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" -msgstr "Perspectief FOV (grad.):" +msgstr "Gezichtsveld (graden):" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Z-Near:" @@ -7874,7 +7871,7 @@ msgstr "Stap:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Sep.:" -msgstr "Separatie:" +msgstr "Scheiding:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "TextureRegion" @@ -9963,6 +9960,13 @@ msgstr "" "U heeft momenteel geen projecten.\n" "Wilt u de officiële voorbeeldprojecten verkennen in de Asset Library?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Toets " @@ -10957,6 +10961,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Merk op: Ingebouwde scripten zijn onderhevig aan bepaalde beperkingen en " +"kunnen niet in een externe editor bewerkt worden." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11079,6 +11085,11 @@ msgid "Total:" msgstr "Totaal:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Profiel exporteren" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Bronpad" @@ -12745,6 +12756,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"De grootte van een Viewport moet groter zijn dan 0 om iets weer te geven." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/or.po b/editor/translations/or.po index 1858bad087..2ce05efe5d 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -9505,6 +9505,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10586,6 +10593,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index eb40e7ecaa..eb84ea26ca 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -42,7 +42,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-26 05:19+0000\n" +"PO-Revision-Date: 2020-04-27 08:25+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -52,7 +52,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2952,13 +2952,12 @@ msgid "Q&A" msgstr "Pytania i odpowiedzi" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Importuj ponownie" +msgstr "ZgÅ‚oÅ› bÅ‚Ä…d" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "WyÅ›lij opiniÄ™ o dokumentacji" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4013,9 +4012,8 @@ msgid "Reimport" msgstr "Importuj ponownie" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Zapisz sceny, re-importuj i zrestartuj" +msgstr "Zapisz sceny, reimportuj i uruchom ponownie" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -5401,7 +5399,7 @@ msgstr "Alt+PrzeciÄ…gnij: PrzesuÅ„" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" -"WciÅ›nij \"v\" by zmienić punkt zaczepienia (pivot), \"Shift+v\" by przesunąć " +"WciÅ›nij \"V\" by zmienić punkt zaczepienia (pivot), \"Shift+V\" by przesunąć " "punkt zaczepienia (podczas poruszania)." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -7309,9 +7307,8 @@ msgid "This operation requires a single selected node." msgstr "Ta operacja wymaga pojedynczego wybranego wÄ™zÅ‚a." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonalna" +msgstr "Automatyczna ortogonalizacja wÅ‚Ä…czona" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9930,6 +9927,13 @@ msgstr "" "Nie posiadasz obecnie żadnych projektów.\n" "Czy chcesz zobaczyć oficjalne przykÅ‚adowe projekty w Bibliotece Zasobów?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Klawisz " @@ -10921,6 +10925,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Uwaga: wbudowane skrypty posiadajÄ… pewne ograniczenia i nie mogÄ… być " +"edytowane przy użyciu zewnÄ™trznego edytora." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11043,6 +11049,11 @@ msgid "Total:" msgstr "CaÅ‚kowity:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Eksportuj profil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Åšcieżka zasobu" @@ -12708,7 +12719,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "Rozmiar wÄ™zÅ‚a Viewport musi być wiÄ™kszy niż 0, by coÅ› wyrenderować." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 70a061783c..646d14c2cf 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -9829,6 +9829,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10948,6 +10955,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 82bd304311..b7102a7cdf 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -12,7 +12,7 @@ # Guilherme Felipe C G Silva <guilhermefelipecgs@gmail.com>, 2017, 2018, 2019. # João Victor Lima <victordevtb@outlook.com>, 2018. # João Vitor de Oliveira Carlos <lopogax@gmail.com>, 2018. -# Joaquim Ferreira <joaquimferreira1996@bol.com.br>, 2016, 2019. +# Joaquim Ferreira <joaquimferreira1996@bol.com.br>, 2016, 2019, 2020. # jonathan railarem <railarem@gmail.com>, 2017. # Lucas Silva <lucasb.hpp@gmail.com>, 2018. # Luiz G. Correia <luizgabriell2.0@gmail.com>, 2017. @@ -28,7 +28,7 @@ # Michel G. Souza <Michelgomesdes@hotmail.com>, 2018. # Caio Northfleet <caio.northfleet@gmail.com>, 2018. # Henrique Combochi <henrique.combochi@gmail.com>, 2018, 2019. -# Gabriel Carvalho <billlmaster@gmail.com>, 2018, 2019. +# Gabriel Carvalho <billlmaster@gmail.com>, 2018, 2019, 2020. # miketangogamer <miketangogamer@gmail.com>, 2018. # Eduardo Abreu <eduo.abreu@gmail.com>, 2018, 2019. # Bruno Miranda Da Silva <brunofreezee@gmail.com>, 2018. @@ -74,7 +74,7 @@ # Rafael Silveira <res883@gmail.com>, 2019. # Luigi <luigimendeszanchett@gmail.com>, 2019. # Nicolas Abril <nicolas.abril@protonmail.ch>, 2019. -# johnnybigoode <jamarson@gmail.com>, 2019. +# johnnybigoode <jamarson@gmail.com>, 2019, 2020. # Zeero <igcdzeero@gmail.com>, 2019. # Gian Penna <gianfrancopen@gmail.com>, 2020. # sribgui <sribgui@gmail.com>, 2020. @@ -82,15 +82,16 @@ # Michael Leocádio <aeronmike@gmail.com>, 2020. # Z <rainromes@gmail.com>, 2020. # Leonardo Dimano <leodimano@live.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. # Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>, 2020. # Richard Urban <redasuio1@gmail.com>, 2020. +# Wellyngton R Weller <well.weller@hotmail.com>, 2020. +# Lucas Araujo <lucassants2808@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2020-04-16 11:03+0000\n" -"Last-Translator: Richard Urban <redasuio1@gmail.com>\n" +"PO-Revision-Date: 2020-04-27 08:25+0000\n" +"Last-Translator: johnnybigoode <jamarson@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -98,16 +99,16 @@ 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.0.1-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "Argumento de tipo inválido para converter(), use TYPE_* constantes." +msgstr "Tipo de argumento inválido para converter(), use TYPE_* constantes." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "Esperado uma string de comprimento 1 (um caractere)." +msgstr "Esperado uma corda de comprimento 1 (um caractere)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -735,11 +736,11 @@ msgstr "Selecionar Todos/Nenhum" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "Adicionar Amostra de uma Trilha de Ãudio" +msgstr "Adicionar Trilha de Clipes de Ãudio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Mudar Deslocamento de InÃcio da Amostra da Trilha de Ãudio" +msgstr "Mudar Deslocamento do InÃcio do Clip de Trilha de Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" @@ -3006,13 +3007,12 @@ msgid "Q&A" msgstr "Perguntas & Respostas" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Reimportar" +msgstr "Reportar bug" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Enviar Feedback de Docs" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3123,14 +3123,13 @@ msgid "" "the \"Use Custom Build\" option should be enabled in the Android export " "preset." msgstr "" -"Isso irá configurar seu projeto para compilações customizadas do Android " -"instalando o template raÃz em \"res://android/build\".\n" -"Em seguida, você pode aplicar modificações e compilar seu próprio APK " -"customizado na exportação (adicionando módulos, alterando o AndroidManifest." -"xml, etc.).\n" -"Note que para fazer uma compilação customizada em vez de usar APKs pre-" -"compilados, a opção \"Usar compilação customizada\" deve estar ativa nas " -"predefinições de exportação do Android." +"Isso vai configurar seu projeto para construções customizadas do Android, " +"instalando o modelo de fonte para \"res://android/build\".\n" +"Você pode então aplicar modificações e construir seu próprio APK na guia " +"Exportação (Adicionando módulos, trocando o AndroidManifest.xml, etc.).\n" +"Note que para fazer uma construção customizada, em vez de usar APKs pre-" +"construÃdos, a opção \"Usar construção customizada\" deve estar ativa nas " +"predefinições de exportação Android." #: editor/editor_node.cpp msgid "" @@ -3662,7 +3661,7 @@ msgstr "Selecionar o Arquivo de Modelo" #: editor/export_template_manager.cpp msgid "Godot Export Templates" -msgstr "Modelos de Exportação do Godot" +msgstr "Modelos de Exportação" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -4071,7 +4070,6 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Salvar cenas, reimportar e reiniciar" @@ -4338,7 +4336,7 @@ msgstr "Abrir Editor" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp msgid "Open Animation Node" -msgstr "Abrir Nó de Animação" +msgstr "Abrir Animação de Nós" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Triangle already exists." @@ -5065,7 +5063,7 @@ msgstr "Download deste asset já está em progresso!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Recently Updated" -msgstr "Atualizado recentemente" +msgstr "Atualizado Recentemente" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Least Recently Updated" @@ -5274,7 +5272,7 @@ msgid "" "Children of containers have their anchors and margins values overridden by " "their parent." msgstr "" -"Filhos de contêineres tem suas posições e margens sobrescritos pelos seus " +"Filhos de contêineres tem suas posições e tamanhos sobrescritos pelos seus " "pais." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -5328,27 +5326,27 @@ msgstr "Centro" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Left Wide" -msgstr "Esquerda Largo" +msgstr "Largura Esquerda" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Top Wide" -msgstr "Superior Largo" +msgstr "Largura Superior" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Right Wide" -msgstr "Direita Largo" +msgstr "Largura Direita" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Bottom Wide" -msgstr "Inferior Largo" +msgstr "Largura inferior" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "VCenter Wide" -msgstr "Centro Vertical Largo" +msgstr "Largura Centro Vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "HCenter Wide" -msgstr "Centro Horizontal Largo" +msgstr "Largura Centro Horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Full Rect" @@ -5376,8 +5374,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" -"Substituir Câmera do Jogo\n" -"Substitui a câmera do jogo com a câmera de visualização do editor." +"Sobrepor câmera de Jogo\n" +"Sobrepõe a câmera de jogo com a janela de exibição da câmera." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5385,8 +5383,8 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" -"Substituir Câmera do Jogo\n" -"Nenhuma instância de jogo em execução." +"Sobrepor câmera de Jogo\n" +"Sem instancia de jogo rodando." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5657,11 +5655,11 @@ msgstr "Visualizar Canvas Scale" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." -msgstr "Máscara de Translação para inserir chaves." +msgstr "Mascara de tradução para inserção de chaves" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "Máscara de Rotação para inserir chaves." +msgstr "Mascara de rotação para inserção de chaves." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." @@ -7370,9 +7368,8 @@ msgid "This operation requires a single selected node." msgstr "Essa operação requer um único nó selecionado." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonal" +msgstr "Ortogonal automático habilitado" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9988,6 +9985,13 @@ msgstr "" "Você não tem nenhum projeto no momento.\n" "Gostaria de explorar projetos de exemplo oficiais na Asset Library?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Chave " @@ -10979,6 +10983,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Nota: Os scripts internos têm algumas limitações e não podem ser editados " +"usando um editor externo." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11101,6 +11107,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportar Perfil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Caminho do Recurso" @@ -12765,6 +12776,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"O tamanho da viewport deve ser maior do que 0 para renderizar qualquer coisa." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index f3b1014123..f7c6f042d2 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -20,8 +20,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-07 13:38+0000\n" -"Last-Translator: Manuela Silva <mmsrs@sky.com>\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" +"Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" "Language: pt_PT\n" @@ -29,7 +29,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2474,7 +2474,7 @@ msgid "" "considered a bug. Please report." msgstr "" "Esta opção foi descontinuada. Situações onde a atualização tem que ser " -"forçada, são agora consideras um defeito. Por favor, reporte." +"forçada, são agora consideras um defeito. Por favor, denuncie." #: editor/editor_node.cpp msgid "Pick a Main Scene" @@ -2940,13 +2940,12 @@ msgid "Q&A" msgstr "Perguntas & Respostas" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Reimportar" +msgstr "Denunciar um Bug" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Enviar Sugestão dos Docs" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3278,7 +3277,7 @@ msgstr "" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "Escolha uma Vista" +msgstr "Escolha um Viewport" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" @@ -3316,7 +3315,7 @@ msgstr "Converter em %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Selected node is not a Viewport!" -msgstr "Nó selecionado não é uma Vista!" +msgstr "Nó selecionado não é um Viewport!" #: editor/editor_properties_array_dict.cpp msgid "Size: " @@ -3461,7 +3460,7 @@ msgstr "Erro na receção da lista de mirrors." #: editor/export_template_manager.cpp msgid "Error parsing JSON of mirror list. Please report this issue!" msgstr "" -"Erro ao analisar a lista de mirrors JSON. Por favor comunique o problema!" +"Erro ao analisar a lista de mirrors JSON. Por favor denuncie o problema!" #: editor/export_template_manager.cpp msgid "" @@ -4000,9 +3999,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "Guardar cenas, reimportar e reiniciar" +msgstr "Guardar Cenas, Reimportar e Reiniciar" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -4046,7 +4044,7 @@ msgstr "Copiar Recurso" #: editor/inspector_dock.cpp msgid "Make Built-In" -msgstr "Tornar incorporado" +msgstr "Tornar Incorporado" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" @@ -5297,7 +5295,7 @@ msgid "" "Overrides game camera with editor viewport camera." msgstr "" "Sobreposição de Câmara de Jogo\n" -"Sobrepõe câmara de jogo com câmara do editor." +"Sobrepõe câmara de jogo com câmara viewport do editor." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5556,7 +5554,7 @@ msgstr "Mostrar Origem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Viewport" -msgstr "Mostrar Vista" +msgstr "Mostrar Viewport" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" @@ -7284,9 +7282,8 @@ msgid "This operation requires a single selected node." msgstr "Esta operação requer um único nó selecionado." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ortogonal" +msgstr "Ortogonal Automático Ativado" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -7477,27 +7474,27 @@ msgstr "Diálogo de transformação..." #: editor/plugins/spatial_editor_plugin.cpp msgid "1 Viewport" -msgstr "1 Vista" +msgstr "1 Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports" -msgstr "2 vistas" +msgstr "2 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports (Alt)" -msgstr "2 vistas (Alt)" +msgstr "2 Viewports (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports" -msgstr "3 vistas" +msgstr "3 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports (Alt)" -msgstr "3 vistas (Alt)" +msgstr "3 Viewports (Alt)" #: editor/plugins/spatial_editor_plugin.cpp msgid "4 Viewports" -msgstr "4 vistas" +msgstr "4 Viewports" #: editor/plugins/spatial_editor_plugin.cpp msgid "Gizmos" @@ -7534,7 +7531,7 @@ msgstr "Ajuste de Escala (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" -msgstr "Configuração de Vista" +msgstr "Configuração do Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" @@ -9899,6 +9896,13 @@ msgstr "" "Atualmente não tem quaisquer projetos.\n" "Gostaria de explorar os projetos de exemplo oficiais na Biblioteca de Ativos?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Tecla " @@ -10889,6 +10893,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Nota: Scripts incorporados têm algumas limitações e não podem ser editados " +"com um editor externo." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11011,6 +11017,11 @@ msgid "Total:" msgstr "Total:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportar Perfil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Caminho do recurso" @@ -11466,7 +11477,8 @@ msgstr "O nó retornou uma sequência de saÃda (output) incorreta: " #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" -msgstr "Foi encontrada o bit da sequência mas não o nó na pilha, relate o bug!" +msgstr "" +"Foi encontrada o bit da sequência mas não o nó na pilha, denuncie o bug!" #: modules/visual_script/visual_script.cpp msgid "Stack overflow with stack depth: " @@ -12664,14 +12676,14 @@ msgid "" "obtain a size. Otherwise, make it a RenderTarget and assign its internal " "texture to some node for display." msgstr "" -"Esta vista não está definida como alvo de Renderização. Se pretende " +"Este viewport não está definida como alvo de Renderização. Se pretende " "apresentar o seu conteúdo diretamente no ecrã, torne-a um filho de um " "Control de modo a que obtenha um tamanho. Caso contrário, torne-a um " "RenderTarget e atribua a sua textura interna a outro nó para visualizar." #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "O tamanho do viewport tem de ser maior do que 0 para renderizar." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 28d33d4609..624ae005f2 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -10105,6 +10105,13 @@ msgstr "" "DoreÈ™ti să explorezi exemplele de proiecte oficiale din Librăria de Asset-" "uri?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11245,6 +11252,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportă Profil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index a0e80d0ce8..2344b31e59 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -65,17 +65,17 @@ # Ðндрей БелÑков <andbelandantrus@gmail.com>, 2020. # Artur Tretiak <stikyt@protonmail.com>, 2020. # Smadjavul <o1985af@gmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. # Vinsent Insaider_red <vinsent.in7aider@gmail.com>, 2020. # TMF <themysticalfox@mail.ru>, 2020. # Ivan Kuzmenko <kuzmenko.ivan2002@yandex.com>, 2020. # Super Pracion <superpracion2@gmail.com>, 2020. +# PizzArt <7o7goo7o7@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-10 09:09+0000\n" -"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" +"Last-Translator: PizzArt <7o7goo7o7@gmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -84,7 +84,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2990,13 +2990,12 @@ msgid "Q&A" msgstr "ВопроÑÑ‹ и ответы" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Переимпортировать" +msgstr "Сообщить об ошибке" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Отправить отзыв о документации" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4050,7 +4049,6 @@ msgid "Reimport" msgstr "Переимпортировать" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Сохранить Ñцены, переимпортировать и перезапуÑтить" @@ -5249,7 +5247,6 @@ msgid "" msgstr "Ð¯ÐºÐ¾Ñ€Ñ Ð¸ отÑтупы дочерних контейнеров переопределÑÑŽÑ‚ÑÑ Ð¸Ñ… родителÑми." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Presets for the anchors and margins values of a Control node." msgstr "ПреÑеты значений Ð´Ð»Ñ Ñкорей и отÑтупов узла Control." @@ -5660,9 +5657,8 @@ msgid "Auto Insert Key" msgstr "ÐвтовÑтавка ключа" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Animation Key and Pose Options" -msgstr "Опции анимационных Ключей и Позы" +msgstr "ÐаÑтройки ключевых кадров и поз" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -9108,12 +9104,10 @@ msgid "Perform the texture lookup." msgstr "ВыполнÑет поиÑк текÑтуры." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform lookup." -msgstr "Изменить текÑтурную единицу" +msgstr "ПоиÑк кубичеÑкой текÑтуры." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform lookup." msgstr "Равномерный поиÑк 2D-текÑтур." @@ -9966,6 +9960,13 @@ msgstr "" "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñƒ Ð²Ð°Ñ Ð½ÐµÑ‚ никаких проектов.\n" "Хотите изучить официальные примеры в Библиотеке реÑурÑов?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Клавиша " @@ -10149,7 +10150,7 @@ msgstr "ÐаÑтройки Ñохранены нормально." #: editor/project_settings_editor.cpp #, fuzzy msgid "Moved Input Action Event" -msgstr "Добавить дейÑтвие" +msgstr "Событие ввода дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¾" #: editor/project_settings_editor.cpp msgid "Override for Feature" @@ -10396,9 +10397,8 @@ msgstr "" "Сравните параметры Ñчетчика." #: editor/rename_dialog.cpp -#, fuzzy msgid "Per-level Counter" -msgstr "Счетчик уровнÑ" +msgstr "Счетчик Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ уровнÑ" #: editor/rename_dialog.cpp msgid "If set the counter restarts for each group of child nodes" @@ -10964,6 +10964,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Примечание: вÑтроенные Ñкрипты имеют неÑколько ограничений и не могут быть " +"редактированы через внешний редактор." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11034,9 +11036,8 @@ msgid "Copy Error" msgstr "Копировать ошибку" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Video RAM" -msgstr "Видео памÑÑ‚ÑŒ" +msgstr "ВидеопамÑÑ‚ÑŒ" #: editor/script_editor_debugger.cpp msgid "Skip Breakpoints" @@ -11088,6 +11089,11 @@ msgid "Total:" msgstr "Ð’Ñего:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "ÐкÑпортировать профиль" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Путь к реÑурÑу" @@ -11349,7 +11355,6 @@ msgid "GridMap Fill Selection" msgstr "Залить выделенную GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" msgstr "Ð’Ñтавить выделенную Ñетку" @@ -12750,7 +12755,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "Размер окна проÑмотра должен быть больше 0 Ð´Ð»Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð°." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/si.po b/editor/translations/si.po index f46a3ca292..2eb9cad3f8 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -9581,6 +9581,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10666,6 +10673,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index d0fe10184e..d5730a7db9 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -9,12 +9,11 @@ # Michal <alladinsiffon@gmail.com>, 2019. # Richard <rgarlik@gmail.com>, 2019. # Richard Urban <redasuio1@gmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" "Last-Translator: Richard Urban <redasuio1@gmail.com>\n" "Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/" "godot/sk/>\n" @@ -23,7 +22,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 4.0.1-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1679,112 +1678,105 @@ msgid "" "Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Profil '%s' už existuje. Najprv ho Vymažte ako zaÄnete ImportovaÅ¥, import je " +"preruÅ¡ený." #: editor/editor_feature_profile.cpp msgid "Error saving profile to path: '%s'." -msgstr "" +msgstr "Error pri ukladanà profilu do cesty: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Unset" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Current Profile:" -msgstr "VytvoriÅ¥ adresár" +msgstr "Aktuálny Profil:" #: editor/editor_feature_profile.cpp msgid "Make Current" -msgstr "" +msgstr "SpraviÅ¥ Aktuálny" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "Nový" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "" +msgstr "Import" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" -msgstr "" +msgstr "Export" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Available Profiles:" -msgstr "Filter:" +msgstr "Profily k dispozÃcii:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Popis:" +msgstr "Možnosti pre Class" #: editor/editor_feature_profile.cpp msgid "New profile name:" -msgstr "" +msgstr "Nové profilové meno:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "VÅ¡etky vybrané" +msgstr "VymazaÅ¥ Profil" #: editor/editor_feature_profile.cpp msgid "Godot Feature Profile" -msgstr "" +msgstr "Godot Feature Profil" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" -msgstr "" +msgstr "ImportovaÅ¥ Profil(y)" #: editor/editor_feature_profile.cpp msgid "Export Profile" -msgstr "" +msgstr "ExportovaÅ¥ Profil" #: editor/editor_feature_profile.cpp msgid "Manage Editor Feature Profiles" -msgstr "" +msgstr "SpravovaÅ¥ Feature Profily Editora" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select Current Folder" -msgstr "VytvoriÅ¥ adresár" +msgstr "VybraÅ¥ Aktuálny PrieÄinok" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" -msgstr "" +msgstr "Súbor Existuje, PredpÃsaÅ¥?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select This Folder" -msgstr "VytvoriÅ¥ adresár" +msgstr "VybraÅ¥ Tento PrieÄinok" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "" +msgstr "SkopÃrovaÅ¥ Cestu" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "OtvoriÅ¥ súbor" +msgstr "OtvoriÅ¥ v File Manažérovy" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp -#, fuzzy msgid "Show in File Manager" -msgstr "OtvoriÅ¥ súbor" +msgstr "UkázaÅ¥ v File Manažérovy" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "New Folder..." -msgstr "VytvoriÅ¥ adresár" +msgstr "Nový PrieÄinok..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" -msgstr "" +msgstr "ObnoviÅ¥" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" @@ -1792,7 +1784,7 @@ msgstr "VÅ¡etko rozpoznané" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" -msgstr "" +msgstr "VÅ¡etky Súbory (*)" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File" @@ -1823,74 +1815,71 @@ msgstr "UložiÅ¥ súbor" #: editor/editor_file_dialog.cpp msgid "Go Back" -msgstr "" +msgstr "ÃsÅ¥ Naspäť" #: editor/editor_file_dialog.cpp msgid "Go Forward" -msgstr "" +msgstr "ÃsÅ¥ Dopredu" #: editor/editor_file_dialog.cpp msgid "Go Up" -msgstr "" +msgstr "ÃsÅ¥ Hore" #: editor/editor_file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "" +msgstr "Prepnúť Skryté Súbory" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "" +msgstr "Prepnúť Obľúbené" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" -msgstr "" +msgstr "Prepnúť Mode" #: editor/editor_file_dialog.cpp msgid "Focus Path" -msgstr "" +msgstr "ZameraÅ¥ Cestu" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" -msgstr "" +msgstr "Posunúť obľúbené VyÅ¡Å¡ie" #: editor/editor_file_dialog.cpp msgid "Move Favorite Down" -msgstr "" +msgstr "Posunúť Obľúbené Nižšie" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go to previous folder." -msgstr "VytvoriÅ¥ adresár" +msgstr "ÃsÅ¥ do predchádzajúceho prieÄinka." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go to next folder." -msgstr "VytvoriÅ¥ adresár" +msgstr "ÃsÅ¥ do ÄalÅ¡ieho prieÄinka." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder." -msgstr "VytvoriÅ¥ adresár" +msgstr "ÃsÅ¥ do parent folder." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Refresh files." -msgstr "" +msgstr "ObnoviÅ¥ súbory." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." -msgstr "" +msgstr "(Od)obľúbiÅ¥ aktuálny prieÄinok." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle the visibility of hidden files." -msgstr "" +msgstr "Prepnúť viditeľnosÅ¥ skrytých súborov." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "" +msgstr "ZobraziÅ¥ veci ako mriežku náhľadov." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." -msgstr "" +msgstr "ZobraziÅ¥ veci ako list." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" @@ -1900,7 +1889,7 @@ msgstr "PrieÄinky a Súbory:" #: editor/plugins/style_box_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Preview:" -msgstr "" +msgstr "Ako to bude vyzeraÅ¥:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File:" @@ -1908,25 +1897,27 @@ msgstr "Súbor:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Must use a valid extension." -msgstr "" +msgstr "MusÃte použiÅ¥ platné rozÅ¡Ãrenie." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "" +msgstr "SkenZdrojov" #: editor/editor_file_system.cpp msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Sú tu viacero importérov pre rozliÄné typy ukazujúce do súboru, import " +"preruÅ¡ený" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "" +msgstr "(Re)Importovanie Asset-ov" #: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Top" -msgstr "" +msgstr "Top" #: editor/editor_help.cpp msgid "Class:" @@ -1935,175 +1926,164 @@ msgstr "Trieda:" #: editor/editor_help.cpp editor/scene_tree_editor.cpp #: editor/script_create_dialog.cpp msgid "Inherits:" -msgstr "" +msgstr "Inherit-y:" #: editor/editor_help.cpp msgid "Inherited by:" -msgstr "" +msgstr "Zdedené použÃvateľom:" #: editor/editor_help.cpp -#, fuzzy msgid "Description" -msgstr "Popis:" +msgstr "Popisok" #: editor/editor_help.cpp msgid "Online Tutorials" -msgstr "" +msgstr "Online Tutoriáli" #: editor/editor_help.cpp msgid "Properties" -msgstr "" +msgstr "Vlastnosti" #: editor/editor_help.cpp msgid "override:" -msgstr "" +msgstr "PredpÃsaÅ¥:" #: editor/editor_help.cpp -#, fuzzy msgid "default:" -msgstr "NaÄÃtaÅ¥ predvolené" +msgstr "Å tandard:" #: editor/editor_help.cpp msgid "Methods" -msgstr "" +msgstr "Metódy" #: editor/editor_help.cpp -#, fuzzy msgid "Theme Properties" -msgstr "Filter:" +msgstr "Vlastnosti Témy" #: editor/editor_help.cpp -#, fuzzy msgid "Enumerations" -msgstr "Popis:" +msgstr "VýpoÄty" #: editor/editor_help.cpp -#, fuzzy msgid "Constants" -msgstr "KonÅ¡tanty:" +msgstr "KonÅ¡tanty" #: editor/editor_help.cpp -#, fuzzy msgid "Property Descriptions" -msgstr "Popis:" +msgstr "Popisok Vlastnosti" #: editor/editor_help.cpp -#, fuzzy msgid "(value)" -msgstr "Hodnota:" +msgstr "(hodnota)" #: editor/editor_help.cpp msgid "" "There is currently no description for this property. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" +"Zatiaľ tu nenà žiadny popisok pre túto vlastnosÅ¥. ProsÃm pomôžte nám pomocou " +"[color=$color][url=$url]prispetÃm jedného[/url][/color]!" #: editor/editor_help.cpp -#, fuzzy msgid "Method Descriptions" -msgstr "Popis:" +msgstr "Popisky Metód" #: editor/editor_help.cpp msgid "" "There is currently no description for this method. Please help us by [color=" "$color][url=$url]contributing one[/url][/color]!" msgstr "" +"Zatiaľ tu nenà žiadny popisok pre túto metódu. ProsÃm pomôžte nám pomocou " +"[color=$color][url=$url]prispetÃm jedného[/url][/color]!" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Search Help" -msgstr "" +msgstr "VyhľadaÅ¥ Pomoc" #: editor/editor_help_search.cpp msgid "Case Sensitive" -msgstr "" +msgstr "RozliÅ¡uje malé a veľké pÃsmená" #: editor/editor_help_search.cpp msgid "Show Hierarchy" -msgstr "" +msgstr "UkázaÅ¥ Hierarchiu" #: editor/editor_help_search.cpp msgid "Display All" -msgstr "" +msgstr "ZobraziÅ¥ VÅ¡etko" #: editor/editor_help_search.cpp msgid "Classes Only" -msgstr "" +msgstr "Iba Class-y" #: editor/editor_help_search.cpp msgid "Methods Only" -msgstr "" +msgstr "Iba Metódy" #: editor/editor_help_search.cpp -#, fuzzy msgid "Signals Only" -msgstr "Signály:" +msgstr "Iba Signály" #: editor/editor_help_search.cpp -#, fuzzy msgid "Constants Only" -msgstr "KonÅ¡tanty:" +msgstr "Iba KonÅ¡tanty" #: editor/editor_help_search.cpp msgid "Properties Only" -msgstr "" +msgstr "Iba Vlastnosti" #: editor/editor_help_search.cpp msgid "Theme Properties Only" -msgstr "" +msgstr "Iba Vlastnosti Témy" #: editor/editor_help_search.cpp msgid "Member Type" -msgstr "" +msgstr "Typ ÄŒlena" #: editor/editor_help_search.cpp -#, fuzzy msgid "Class" -msgstr "Trieda:" +msgstr "Class" #: editor/editor_help_search.cpp -#, fuzzy msgid "Method" -msgstr "Prejdite na Metódu" +msgstr "Metóda" #: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Signály" +msgstr "Signál" #: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constant" -msgstr "" +msgstr "KonÅ¡tant" #: editor/editor_help_search.cpp msgid "Property" -msgstr "" +msgstr "VlastnosÅ¥" #: editor/editor_help_search.cpp -#, fuzzy msgid "Theme Property" -msgstr "Filter:" +msgstr "VlastnosÅ¥ Témy" #: editor/editor_inspector.cpp editor/project_settings_editor.cpp msgid "Property:" -msgstr "" +msgstr "VlastnosÅ¥:" #: editor/editor_inspector.cpp msgid "Set" -msgstr "" +msgstr "NastaviÅ¥" #: editor/editor_inspector.cpp msgid "Set Multiple:" -msgstr "" +msgstr "NastaviÅ¥ Viac:" #: editor/editor_log.cpp msgid "Output:" -msgstr "" +msgstr "Output:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "OdstrániÅ¥ výber" +msgstr "SkopÃrovaÅ¥ Výber" #: editor/editor_log.cpp editor/editor_network_profiler.cpp #: editor/editor_profiler.cpp editor/editor_properties.cpp @@ -2113,177 +2093,182 @@ msgstr "OdstrániÅ¥ výber" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "" +msgstr "VyÄistiÅ¥" #: editor/editor_log.cpp -#, fuzzy msgid "Clear Output" -msgstr "Popis:" +msgstr "VyÄistiÅ¥ Output" #: editor/editor_network_profiler.cpp editor/editor_node.cpp #: editor/editor_profiler.cpp msgid "Stop" -msgstr "" +msgstr "Stop" #: editor/editor_network_profiler.cpp editor/editor_profiler.cpp #: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp msgid "Start" -msgstr "" +msgstr "Å tart" #: editor/editor_network_profiler.cpp msgid "%s/s" -msgstr "" +msgstr "%s/s" #: editor/editor_network_profiler.cpp msgid "Down" -msgstr "" +msgstr "Dole" #: editor/editor_network_profiler.cpp msgid "Up" -msgstr "" +msgstr "Hore" #: editor/editor_network_profiler.cpp editor/editor_node.cpp msgid "Node" -msgstr "" +msgstr "Node" #: editor/editor_network_profiler.cpp msgid "Incoming RPC" -msgstr "" +msgstr "Prichádzajúce RPC" #: editor/editor_network_profiler.cpp msgid "Incoming RSET" -msgstr "" +msgstr "Prichádzajúci RSET" #: editor/editor_network_profiler.cpp msgid "Outgoing RPC" -msgstr "" +msgstr "Vychádzajúce RPC" #: editor/editor_network_profiler.cpp msgid "Outgoing RSET" -msgstr "" +msgstr "Vychádzajúci RSET" #: editor/editor_node.cpp editor/project_manager.cpp msgid "New Window" -msgstr "" +msgstr "Nové Okno" #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "Importované zdroje nemôžu byÅ¥ uložené." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp msgid "OK" -msgstr "" +msgstr "OK" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" -msgstr "" +msgstr "Error pri ukladanà prostriedku!" #: editor/editor_node.cpp msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" +"Tento prostriedok nemôže byÅ¥ uložený lebo nepatrà editovanej scéne. Najprv " +"ho spravte jedineÄným." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." -msgstr "" +msgstr "UložiÅ¥ Prostriedok Ako..." #: editor/editor_node.cpp msgid "Can't open file for writing:" -msgstr "" +msgstr "Nie je možné otvoriÅ¥ súbor pre pÃsanie:" #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "" +msgstr "Požadovaný formát súboru je neznámy:" #: editor/editor_node.cpp msgid "Error while saving." -msgstr "" +msgstr "Error pri ukladanÃ." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "" +msgstr "Nedá sa otvoriÅ¥ '%s'. Súbor mohol byÅ¥ presunutý alebo vymazaný." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "" +msgstr "Error pri analýze '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "" +msgstr "NeoÄakávaný koniec súboru '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "" +msgstr "Chýba '%s' alebo jeho závislosti." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "" +msgstr "Error pri naÄÃtavanà '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "" +msgstr "Ukladanie Scény" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "" +msgstr "Analyzovanie" #: editor/editor_node.cpp msgid "Creating Thumbnail" -msgstr "" +msgstr "Vytváranie Náhľadu" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." -msgstr "" +msgstr "Tátu operáciu nie je možné vykonaÅ¥ bez tree root-u." #: editor/editor_node.cpp msgid "" "This scene can't be saved because there is a cyclic instancing inclusion.\n" "Please resolve it and then attempt to save again." msgstr "" +"Táto scéna nemôže byÅ¥ uložená lebo je tu cyklické instancovanie inklúzie.\n" +"ProsÃm vyrieÅ¡te to a skúste to znova." #: editor/editor_node.cpp msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" +"Nedá sa uložiÅ¥ scéna. Pravdepodobne (inÅ¡tancie alebo dediÄstvo) nemôžu byÅ¥ " +"spokojné." #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "Scéna sa nedá predpÃsaÅ¥ keÄ je stále otvorená!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "Nedá sa naÄÃtaÅ¥ MeshLibrary lebo sa spája!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "Error pri ukladanà MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "" +msgstr "Nedá sa naÄÃtaÅ¥ TileSet lebo sa spája!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "Error pri ukladanà TileSet-u!" #: editor/editor_node.cpp msgid "Error trying to save layout!" -msgstr "" +msgstr "Error pri ukladanà layout-i!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "" +msgstr "Predvolený editor layout je prepÃsaný." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "" +msgstr "Meno Layout-u sa nenaÅ¡lo!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "" +msgstr "Obnovené predvolené rozloženie na základné nastavenia." #: editor/editor_node.cpp msgid "" @@ -2291,18 +2276,26 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"Tento prostriedok patrà scéne ktorá bola importovaná, takže nenà " +"editovateľný.\n" +"ProsÃm preÄÃtajte si dokumentáciu na importovanie scén aby ste tomu viac " +"pochopili." #: editor/editor_node.cpp msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" +"Tento prostriedok patrà scéne ktorá bola inÅ¡tancovaná alebo zdedená.\n" +"Zmeny sa nezanechajú po uloženà aktuálnej scény." #: editor/editor_node.cpp msgid "" "This resource was imported, so it's not editable. Change its settings in the " "import panel and then re-import." msgstr "" +"Tento prostriedok bol importovaný, takže nenà editovateľný. Zmeňte jeho " +"nastavenia v import panely a potom stlaÄÅ¥e re-import." #: editor/editor_node.cpp msgid "" @@ -2311,6 +2304,11 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"Táto scéna bola importovaná, takže sa zmeny neuložia.\n" +"Jej inÅ¡tancovanÃm alebo zdedenÃm povolÃte to že môžete robiÅ¥ zmeny v tejto " +"scéne.\n" +"ProsÃm preÄÃtajte si dokumentáciu na importovanie scén aby ste tomu viac " +"pochopili." #: editor/editor_node.cpp msgid "" @@ -2318,203 +2316,215 @@ msgid "" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" +"Toto je remote objekt, takže sa zmeny neuložia.\n" +"ProsÃm preÄÃtajte si dokumentáciu o debbugging aby ste tomu viac pochopili." #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "" +msgstr "Nieje definovaná žiadna scéna na spustenie." #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." -msgstr "" +msgstr "Aktuálna scéna sa nikdy neuložila, prosÃm uložte ju pred spustenÃm." #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "" +msgstr "Subprocess sa nedá spustiÅ¥!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" -msgstr "" +msgstr "OtvoriÅ¥ Scénu" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "" +msgstr "OtvoriÅ¥ Base Scene" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "OtvoriÅ¥" +msgstr "Rýchle Otvorenie..." #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "" +msgstr "Rýchle Otvorenie Scény..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "" +msgstr "Rýchle Otvorenie Scriptu..." #: editor/editor_node.cpp -#, fuzzy msgid "Save & Close" -msgstr "UložiÅ¥ súbor" +msgstr "UložiÅ¥ & ZatvoriÅ¥" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" -msgstr "" +msgstr "Chcete uložiÅ¥ zmeny do '%s' pred zatvorenÃm?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." -msgstr "" +msgstr "Uložené %s upravené zdroje." #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "" +msgstr "Na uloženie scény je potrebný root node." #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "" +msgstr "UložiÅ¥ Scénu Ako..." #: editor/editor_node.cpp msgid "No" -msgstr "" +msgstr "Nie" #: editor/editor_node.cpp msgid "Yes" -msgstr "" +msgstr "ÃNO" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" msgstr "" +"Táto scéna eÅ¡te nikdy nebola uložená. Chcete ju uložiÅ¥ predtým ako ju " +"zapnete?" #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." -msgstr "" +msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez scény." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "ExportovaÅ¥ Mesh Library" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "" +msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez root node-u." #: editor/editor_node.cpp msgid "Export Tile Set" -msgstr "" +msgstr "ExportovaÅ¥ Tile Set" #: editor/editor_node.cpp msgid "This operation can't be done without a selected node." -msgstr "" +msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez vybraného node-u." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "" +msgstr "Aktuálna scéna sa neuložila. Chcete ju aj tak otvoriÅ¥?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "" +msgstr "Nemožno naÄÃtaÅ¥ scénu, ktorá nikdy nebola uložená." #: editor/editor_node.cpp msgid "Revert" -msgstr "" +msgstr "Revert" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "" +msgstr "Túto akciu nie je možné vrátiÅ¥ späť. Chcete RevertovatÅ¥ aj tak?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "" +msgstr "Rýchle Spustenie Scény..." #: editor/editor_node.cpp msgid "Quit" -msgstr "" +msgstr "OdÃsÅ¥" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "" +msgstr "OdÃsÅ¥ z editora?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "" +msgstr "OtvoriÅ¥ Manažéra Projektov?" #: editor/editor_node.cpp -#, fuzzy msgid "Save & Quit" -msgstr "UložiÅ¥ súbor" +msgstr "UložiÅ¥ & UkonÄiÅ¥" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" -msgstr "" +msgstr "UložiÅ¥ zmeny do nasledujúcich scén pred ukonÄenÃm?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" -msgstr "" +msgstr "UložiÅ¥ zmeny nasledujúcich scén pred otvorenÃm Manažéra Projektov?" #: editor/editor_node.cpp msgid "" "This option is deprecated. Situations where refresh must be forced are now " "considered a bug. Please report." msgstr "" +"Táto možnosÅ¥ je zastaraná. Situácie, v ktorých je potrebné obnovenie, sa " +"teraz považujú za chybu. ProsÃm, nahláste." #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "" +msgstr "Vyberte hlavnú scénu" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "" +msgstr "ZavrieÅ¥ Scénu" #: editor/editor_node.cpp -#, fuzzy msgid "Reopen Closed Scene" -msgstr "OtvoriÅ¥ súbor(y)" +msgstr "PreotvoriÅ¥ Zatvorenú Scénu" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" +"Addon plugin nie je možné povoliÅ¥ pri: '% s' analýze konfigurácie zlyhalo." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." msgstr "" +"Nepodarilo sa nájsÅ¥ script field pre addon plugin v: 'res://addons/%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "" +msgstr "Nepodarilo sa naÄÃtaÅ¥ addon script z cesty: '%s'." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." msgstr "" +"Nepodarilo sa nájsÅ¥ addon script z cesty: '%s' Vyzerá to tak že by mohol byÅ¥ " +"problém v kóde, prosÃm skontrolujte syntax." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" +"Nepodarilo sa naÄÃtaÅ¥ addon script z cesty: '%s' Base type nenà EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" +"Nepodarilo sa naÄÃtaÅ¥ addon script z cesty: '%s' Script nenà v tool móde." #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" +"Scéna '%s' bola automaticky importovaná, takže nemôže byÅ¥ modifikovaná.\n" +"Aby ste v nej mohli spraviÅ¥ úpravy, môžete vytvoriÅ¥ novú zdedenú scénu." #: editor/editor_node.cpp msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to " "open the scene, then save it inside the project path." msgstr "" +"Error pri naÄÃtavanÃ, musà byÅ¥ vo vnútri projektovej cesty. Použite 'Import' " +"aby ste otvorili scénu, a potom ju uložte do projektovej cesty." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "" +msgstr "Scéna '%s' má zniÄené závislosti:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" -msgstr "" +msgstr "VyÄistiÅ¥ Posledné Scény" #: editor/editor_node.cpp msgid "" @@ -2522,6 +2532,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"EÅ¡te ste nedefinovali hlavnú scénu, chcete nejakú vybraÅ¥?\n" +"Neskôr ju môžete zmeniÅ¥ v \"Nastaveniach Projektu\" pod kategóriou " +"'application'." #: editor/editor_node.cpp msgid "" @@ -2529,6 +2542,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Vybraná scéna '%s' neexistuje, vybraÅ¥ platnú?\n" +"Neskôr ju môžete zmeniÅ¥ v \"Nastaveniach Projekta\" pod kategóriou " +"'application'." #: editor/editor_node.cpp msgid "" @@ -2536,147 +2552,147 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Vybraná scéna '%s' nenà scene file, vybraÅ¥ platnú scénu?\n" +"Neskôr ju môžete zmeniÅ¥ v \"Nastaveniach Projekta\" pod kategóriou " +"'application'." #: editor/editor_node.cpp msgid "Save Layout" -msgstr "" +msgstr "UložiÅ¥ Layout" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "" +msgstr "OdstrániÅ¥ Layout" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "Predvolené" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp msgid "Show in FileSystem" -msgstr "" +msgstr "UkázaÅ¥ v FileSystéme" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "" +msgstr "SpustiÅ¥ Túto Scénu" #: editor/editor_node.cpp msgid "Close Tab" -msgstr "" +msgstr "ZavrieÅ¥ Kartu" #: editor/editor_node.cpp msgid "Undo Close Tab" -msgstr "" +msgstr "Naspäť OtvoriÅ¥ Kartu" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "ZavrieÅ¥ Ostatné Karty" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "ZavrieÅ¥ Karty na Pravo" #: editor/editor_node.cpp msgid "Close All Tabs" -msgstr "" +msgstr "ZatvoriÅ¥ vÅ¡etky Karty" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "" +msgstr "Prepnúť Kartu Scény" #: editor/editor_node.cpp msgid "%d more files or folders" -msgstr "" +msgstr "%d viac súborov alebo prieÄinkov" #: editor/editor_node.cpp -#, fuzzy msgid "%d more folders" -msgstr "VytvoriÅ¥ adresár" +msgstr "%d viac prieÄinkov" #: editor/editor_node.cpp msgid "%d more files" -msgstr "" +msgstr "%d viac súborov" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "" +msgstr "PozÃcia Dock-u" #: editor/editor_node.cpp msgid "Distraction Free Mode" -msgstr "" +msgstr "Režim bez rozptyľovania" #: editor/editor_node.cpp msgid "Toggle distraction-free mode." -msgstr "" +msgstr "Prepnúť režim bez rozptyľovania." #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "" +msgstr "PridaÅ¥ novú scénu." #: editor/editor_node.cpp msgid "Scene" -msgstr "" +msgstr "Scéna" #: editor/editor_node.cpp msgid "Go to previously opened scene." -msgstr "" +msgstr "ÃsÅ¥ do naposledy otvorenej scény." #: editor/editor_node.cpp -#, fuzzy msgid "Copy Text" -msgstr "KopÃrovaÅ¥" +msgstr "KopÃrovaÅ¥ Text" #: editor/editor_node.cpp msgid "Next tab" -msgstr "" +msgstr "ÄŽalÅ¡ia karta" #: editor/editor_node.cpp msgid "Previous tab" -msgstr "" +msgstr "Minulá karta" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "FiltrovaÅ¥ Súbory..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "Operácie zo súbormi scén." #: editor/editor_node.cpp msgid "New Scene" -msgstr "" +msgstr "Nová Scéna" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "" +msgstr "Nové Zdedené Scény..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "" +msgstr "OtvoriÅ¥ Scénu..." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "" +msgstr "OtvoriÅ¥ Posledné" #: editor/editor_node.cpp msgid "Save Scene" -msgstr "" +msgstr "UložiÅ¥ Scénu" #: editor/editor_node.cpp -#, fuzzy msgid "Save All Scenes" -msgstr "UložiÅ¥ súbor" +msgstr "UložiÅ¥ VÅ¡etky Scény" #: editor/editor_node.cpp msgid "Convert To..." -msgstr "" +msgstr "KonvertovaÅ¥ Do..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "MeshLibrary..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "TileSet..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -2686,80 +2702,81 @@ msgstr "Späť" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Redo" -msgstr "" +msgstr "PrerobiÅ¥" #: editor/editor_node.cpp msgid "Revert Scene" -msgstr "" +msgstr "VrátiÅ¥ Scénu" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "" +msgstr "ZmieÅ¡anosti projektových alebo scénových wide tool-ov." #: editor/editor_node.cpp editor/project_manager.cpp #: editor/script_create_dialog.cpp msgid "Project" -msgstr "" +msgstr "Projekt" #: editor/editor_node.cpp msgid "Project Settings..." -msgstr "" +msgstr "Nastavenia Projektu..." #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Version Control" -msgstr "" +msgstr "Kontrola Verzie" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Set Up Version Control" -msgstr "" +msgstr "NastaviÅ¥ Kontrolu Verizie" #: editor/editor_node.cpp msgid "Shut Down Version Control" -msgstr "" +msgstr "Vypnúť Kontrolu Verzie" #: editor/editor_node.cpp -#, fuzzy msgid "Export..." -msgstr "UpraviÅ¥..." +msgstr "Export..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "InÅ¡talovaÅ¥ Android Build Template..." #: editor/editor_node.cpp msgid "Open Project Data Folder" -msgstr "" +msgstr "OtvoriÅ¥ Project Data Folder" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" -msgstr "" +msgstr "Nástroje" #: editor/editor_node.cpp msgid "Orphan Resource Explorer..." -msgstr "" +msgstr "Orphan Resource Explorer..." #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "" +msgstr "OdÃsÅ¥ do Listu Projektov" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "" +msgstr "Debug" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "" +msgstr "Deploy-ovanie z Remote Debug-om" #: editor/editor_node.cpp msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" +"Pri exportovanà alebo deploy-ovanÃ, súbor resulting executable sa pokúsi o " +"pripojenie do IP vášho poÄÃtaÄa aby mohol byÅ¥ debugg-ovaný." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" -msgstr "" +msgstr "Malý Deploy z Network FS" #: editor/editor_node.cpp msgid "" @@ -2770,30 +2787,39 @@ msgid "" "On Android, deploy will use the USB cable for faster performance. This " "option speeds up testing for games with a large footprint." msgstr "" +"KeÄ bude povolená táto možnosÅ¥, export alebo deploy vyprodukujú menej \n" +"súboru executable.\n" +"Filesystém bude z projektu poskytovaný editorom v sieti. Na Androide, pre " +"deploy budete potrebovaÅ¥ USB kábel \n" +"rýchlejÅ¡Ã výkon. Táto možnosÅ¥ zrýchľuje proces testovania." #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "" +msgstr "Viditeľné Tvary KolÃzie" #: editor/editor_node.cpp msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" +"Tvary KolÃzie a raycast node-y (pre 2D a 3D) budú viditeľné po spustenà hry " +"ak budete maÅ¥ zapnutú túto možnosÅ¥." #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "" +msgstr "Viditeľná Navigácia" #: editor/editor_node.cpp msgid "" "Navigation meshes and polygons will be visible on the running game if this " "option is turned on." msgstr "" +"NavigaÄné mesh-e a polygony budú viditeľné po spustenà hry ak budete maÅ¥ " +"zapnutú túto možnosÅ¥." #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "" +msgstr "Zmeny Synchronizácie Scény" #: editor/editor_node.cpp msgid "" @@ -2802,10 +2828,14 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"KeÄ zapnete túto možnosÅ¥, akékoľvek zmeny v scéne v editore budú náhradné so " +"spustenou hrou.\n" +"KeÄ je použitá na diaľku v zariadenÃ, je to viac efektÃvne z network " +"filesystémom." #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "" +msgstr "Zmeny Synchronizácie Scriptu" #: editor/editor_node.cpp msgid "" @@ -2814,60 +2844,62 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"KeÄ je zapnutá táto MožnosÅ¥, akýkoľvek uložený script bude znovu naÄÃtaný v " +"spustenej hre.\n" +"KeÄ je použitá na diaľku zo zariadenia, toto je viac efektÃvnejÅ¡ie z network " +"filesystémom." #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" msgstr "Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Editor Settings..." -msgstr "Prechody" +msgstr "Nastavenia Editora..." #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "" +msgstr "Layout Editora" #: editor/editor_node.cpp msgid "Take Screenshot" -msgstr "" +msgstr "SpraviÅ¥ SnÃmku Obrazovky" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "" +msgstr "SnÃmky obrázky sú uložené v Editor Data/Settings Folder." #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "" +msgstr "Prepnúť na Celú Obrazovku" #: editor/editor_node.cpp msgid "Toggle System Console" -msgstr "" +msgstr "Prepnúť Systémovú Konzolu" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "" +msgstr "OtvoriÅ¥ Editor Data/Settings Folder" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "" +msgstr "OtvoriÅ¥ prieÄinok Editor Data" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" -msgstr "" +msgstr "OtvoriÅ¥ PrieÄinok Editor Settings" #: editor/editor_node.cpp msgid "Manage Editor Features..." -msgstr "" +msgstr "SpravovaÅ¥ Funkcie Editora..." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Export Templates..." -msgstr "VÅ¡etky vybrané" +msgstr "SpravovaÅ¥ Export Templates..." #: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp msgid "Help" -msgstr "" +msgstr "Pomoc" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp @@ -2876,24 +2908,24 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp editor/rename_dialog.cpp msgid "Search" -msgstr "" +msgstr "VyhľadaÅ¥" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" -msgstr "" +msgstr "Online Dokumentácie" #: editor/editor_node.cpp msgid "Q&A" -msgstr "" +msgstr "Q&A" #: editor/editor_node.cpp msgid "Report a Bug" -msgstr "" +msgstr "NahlásiÅ¥ Bugy" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "PoslaÅ¥ spätnú väzbu Dokumentácie" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -2905,95 +2937,92 @@ msgstr "O nás" #: editor/editor_node.cpp msgid "Play the project." -msgstr "" +msgstr "SpustiÅ¥ projekt." #: editor/editor_node.cpp msgid "Play" -msgstr "" +msgstr "SpustiÅ¥" #: editor/editor_node.cpp msgid "Pause the scene execution for debugging." -msgstr "" +msgstr "Pozastavenie vykonávania scény kvôli debugg-ovaniu." #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "PozastaviÅ¥ Scénu" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "ZastaviÅ¥ scénu." #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "SpustiÅ¥ editovanú scénu." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "SpustiÅ¥ Scénu" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "" +msgstr "SpustiÅ¥ vlastnú scénu" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "" +msgstr "SpustiÅ¥ Vlastnú Scénu" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "Zmena video driver-u vyžaduje reÅ¡tart editora." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp -#, fuzzy msgid "Save & Restart" -msgstr "UložiÅ¥ súbor" +msgstr "UložiÅ¥ & ReÅ¡tartovaÅ¥" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." -msgstr "" +msgstr "OtáÄa sa, keÄ sa okno editora redistribuuje." #: editor/editor_node.cpp -#, fuzzy msgid "Update Continuously" -msgstr "Priebežný" +msgstr "AktualizovaÅ¥ priebežne" #: editor/editor_node.cpp msgid "Update When Changed" -msgstr "" +msgstr "AktualizovaÅ¥ po Zmene" #: editor/editor_node.cpp msgid "Hide Update Spinner" -msgstr "" +msgstr "SkryÅ¥ aktualizáciu Spinner" #: editor/editor_node.cpp msgid "FileSystem" -msgstr "" +msgstr "FileSystém" #: editor/editor_node.cpp msgid "Inspector" -msgstr "" +msgstr "InÅ¡pektor" #: editor/editor_node.cpp msgid "Expand Bottom Panel" -msgstr "" +msgstr "ExpandovaÅ¥ Spodný Panel" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "Výstup" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "" +msgstr "NeukladaÅ¥" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Android build template chýba, prosÃm nainÅ¡talujte prÃsluÅ¡né Å¡ablóny." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "VÅ¡etky vybrané" +msgstr "SpravovaÅ¥ Å ablóny" #: editor/editor_node.cpp msgid "" @@ -9853,6 +9882,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10973,6 +11009,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "ExportovaÅ¥ Profil" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 8145e5e5d9..a4a668f76b 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -10214,6 +10214,13 @@ msgstr "" "Trenutno nimate projektov.\n" "Želite raziskovati uradne primere projektov v Asset Library?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11354,6 +11361,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Izvozi Projekt" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 19b13a126b..f24645059a 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -9860,6 +9860,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10974,6 +10981,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Eksporto Projektin" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index f83bc8bcd1..52639bbeeb 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -10335,6 +10335,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11490,6 +11497,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Извези пројекат" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 80ff3bc4fa..a2ae9fccea 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -9657,6 +9657,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10749,6 +10756,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index cb1d4c22d6..a03a37b533 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -10154,6 +10154,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Nyckel " @@ -11305,6 +11312,11 @@ msgid "Total:" msgstr "Totalt:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Exportera Projekt" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/ta.po b/editor/translations/ta.po index b93e16a597..7dd9f5f38c 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -9576,6 +9576,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10663,6 +10670,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index 38d8b80709..a6c727fe89 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -9508,6 +9508,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10589,6 +10596,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 3ad01b7d05..e908dde33c 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -5,7 +5,6 @@ # Kaveeta Vivatchai <goodytong@gmail.com>, 2017. # Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018. # Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020. -# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" @@ -9889,6 +9888,13 @@ msgstr "" "คุณยังไม่มีโปรเจà¸à¸•à¹Œà¹ƒà¸” ๆ\n" "ต้à¸à¸‡à¸à¸²à¸£à¸ªà¸³à¸£à¸§à¸ˆà¹‚ปรเจà¸à¸•à¹Œà¸•à¸±à¸§à¸à¸¢à¹ˆà¸²à¸‡à¹ƒà¸™à¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£à¸«à¸£à¸·à¸à¹„ม่?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "ปุ่ม " @@ -11012,6 +11018,11 @@ msgid "Total:" msgstr "ทั้งหมด:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "ส่งà¸à¸à¸à¹‚ปรไฟล์" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸à¸£à¹Œà¸ª" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index e5e8f0ba97..fdb8f76605 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -43,12 +43,13 @@ # HALÄ°L ATAÅž <halillatass@gmail.com>, 2019. # Zsosu Ktosu <zktosu@gmail.com>, 2020. # Mesut Aslan <kontinyu@gmail.com>, 2020. +# Kaan Genç <kaan@kaangenc.me>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-11 12:20+0000\n" -"Last-Translator: Mesut Aslan <kontinyu@gmail.com>\n" +"PO-Revision-Date: 2020-04-23 20:21+0000\n" +"Last-Translator: Anonymous <noreply@weblate.org>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -56,7 +57,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2961,13 +2962,12 @@ msgid "Q&A" msgstr "S&C" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Yeniden İçe Aktar" +msgstr "Hata Bildir" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Belgelendirme Hatası Bildir" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4018,7 +4018,6 @@ msgid "Reimport" msgstr "Yeniden İçe Aktar" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Sahneleri kaydet, tekrar içe aktar ve baÅŸtan baÅŸlat" @@ -5904,16 +5903,15 @@ msgstr "Tekil Dışbükey Åžekil OluÅŸtur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create multiple convex collision shapes for the scene root." -msgstr "" +msgstr "Sahne kökü için birden fazla dışbükey çarpışma ÅŸekli oluÅŸturulamaz." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create any collision shapes." msgstr "Herhangi bir çarpışma ÅŸekli oluÅŸturulamadı." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Shapes" -msgstr "Dışbükey Åžekil[ler] OluÅŸtur" +msgstr "Dışbükey Åžekilleri OluÅŸtur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5969,6 +5967,9 @@ msgid "" "automatically.\n" "This is the most accurate (but slowest) option for collision detection." msgstr "" +"Bir StaticBody oluÅŸturur ve otomatik olarak çokgen tabanlı bir çarpışma " +"ÅŸekli atar.\n" +"Bu, çarpışma tespiti için en doÄŸru (ancak en yavaÅŸ) seçenektir." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" @@ -5983,7 +5984,6 @@ msgstr "" "Bu en hassas (fakat en yavaÅŸ) çarpışma algılama seçeneÄŸidir." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Dışbükey Çarpışma KomÅŸusu OluÅŸtur" @@ -5992,17 +5992,20 @@ msgid "" "Creates a single convex collision shape.\n" "This is the fastest (but least accurate) option for collision detection." msgstr "" +"Tek bir dışbükey çarpışma ÅŸekli oluÅŸturur.\n" +"Bu, çarpışma tespiti için en hızlı (ancak en az doÄŸru) seçenektir." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Collision Siblings" -msgstr "Dışbükey Çarpışma KomÅŸusu OluÅŸtur" +msgstr "Dışbükey Çarpışma KomÅŸuları OluÅŸtur" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" "Creates a polygon-based collision shape.\n" "This is a performance middle-ground between the two above options." msgstr "" +"Poligon bazlı bir çarpışma ÅŸekli oluÅŸtur.\n" +"Bu performans açısından üstteki iki seçeneÄŸin arasındadır." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -6015,6 +6018,10 @@ msgid "" "This can be used instead of the SpatialMaterial Grow property when using " "that property isn't possible." msgstr "" +"Durgun bir anahat kafesi oluÅŸturur. Anahat kafesi normalleri otomatik olarak " +"döndürülecekdir.\n" +"Bu SpatialMaterial Grow özelliÄŸi kullanılamadığı zaman onun yerine " +"kullanılabilir." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" @@ -7298,9 +7305,8 @@ msgid "This operation requires a single selected node." msgstr "Bu iÅŸlem, seçilmiÅŸ tek bir düğüm gerektirir." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Dikey" +msgstr "Otomatik Dikey EtkinleÅŸtirildi" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9585,32 +9591,27 @@ msgid "Export With Debug" msgstr "Hata Ayıklama Ä°le Dışa Aktar" #: editor/project_manager.cpp -#, fuzzy msgid "The path specified doesn't exist." -msgstr "Yol mevcut deÄŸil." +msgstr "Belirtilen yol mevcut deÄŸil." #: editor/project_manager.cpp -#, fuzzy msgid "Error opening package file (it's not in ZIP format)." -msgstr "Paket dosyası açılırken hata oluÅŸtu, zip formatında deÄŸil." +msgstr "Paket dosyası açılırken hata (ZIP formatında deÄŸil)." #: editor/project_manager.cpp -#, fuzzy msgid "" "Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." -msgstr "Geçersiz '.zip' proje dosyası, 'project.godot' dosyası içermiyor." +msgstr "Geçersiz \".zip\" proje dosyası; \"project.godot\" dosyası içermiyor." #: editor/project_manager.cpp msgid "Please choose an empty folder." msgstr "Lütfen boÅŸ bir klasör seçin." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose a \"project.godot\" or \".zip\" file." -msgstr "Lütfen bir 'project.godot' veya '.zip' dosyası seçin." +msgstr "Lütfen bir \"project.godot\" veya \".zip\" dosyası seçin." #: editor/project_manager.cpp -#, fuzzy msgid "This directory already contains a Godot project." msgstr "Bu dizinde zaten bir Godot projesi var." @@ -9920,6 +9921,13 @@ msgstr "" "Herhangi bir projen yok.\n" "Varlık Kütüphanesi'ndeki resmî örnek projeleri incelemek ister misin?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Anahtar " @@ -10309,9 +10317,8 @@ msgid "Suffix" msgstr "Son Ek" #: editor/rename_dialog.cpp -#, fuzzy msgid "Use Regular Expressions" -msgstr "Düzenli Ä°fadeler" +msgstr "Düzenli Ä°fadeler Kullan" #: editor/rename_dialog.cpp msgid "Advanced Options" @@ -10350,9 +10357,8 @@ msgstr "" "Sayaç seçeneklerini karşılaÅŸtırın." #: editor/rename_dialog.cpp -#, fuzzy msgid "Per-level Counter" -msgstr "Seviye Başına sayaç" +msgstr "Seviye Başına Sayaç" #: editor/rename_dialog.cpp msgid "If set the counter restarts for each group of child nodes" @@ -10391,12 +10397,10 @@ msgid "Keep" msgstr "Tut" #: editor/rename_dialog.cpp -#, fuzzy msgid "PascalCase to snake_case" msgstr "DeveÅžekilli'den alt_tireli'ye dönüştür" #: editor/rename_dialog.cpp -#, fuzzy msgid "snake_case to PascalCase" msgstr "alt_tireli'den DeveÅžekilli'ye dönüştür" @@ -10417,9 +10421,8 @@ msgid "Reset" msgstr "Sıfırla" #: editor/rename_dialog.cpp -#, fuzzy msgid "Regular Expression Error" -msgstr "Düzenli Ä°fadeler" +msgstr "Düzenli Ä°fade Hatası" #: editor/rename_dialog.cpp #, fuzzy @@ -10889,9 +10892,8 @@ msgid "Invalid inherited parent name or path." msgstr "Geçersiz devralınan üst ad veya yol." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script path/name is valid." -msgstr "Betik geçerli." +msgstr "Betik yolu/adı geçerli." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9, _ and ." @@ -10918,6 +10920,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"Not: Gömülü betikler bazı sınırlandırmalara mahsustur ve dış bir düzenleyici " +"ile düzenlenemezler." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -10988,7 +10992,6 @@ msgid "Copy Error" msgstr "Hatayı Kopyala" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Video RAM" msgstr "Görüntü BelleÄŸi" @@ -11041,6 +11044,11 @@ msgid "Total:" msgstr "Toplam:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Profil Dışa Aktar" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "Kaynak Yolu" @@ -12392,6 +12400,7 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape static dışında bir modda RigidBody'i desteklemiyor." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12694,6 +12703,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"Herhangi bir ÅŸeyi iÅŸlemek için görüntükapısı boyutu 0'dan büyük olmalıdır." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 60e61d3bf7..46e671a8a8 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-18 00:10+0000\n" +"PO-Revision-Date: 2020-04-20 05:51+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -27,7 +27,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2945,13 +2945,12 @@ msgid "Q&A" msgstr "Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° відповіді" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "Переімпортувати" +msgstr "Повідомити про ваду" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "ÐадіÑлати відгук щодо документації" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4006,7 +4005,6 @@ msgid "Reimport" msgstr "Переімпортувати" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" msgstr "Зберегти Ñцени, повторно імпортувати Ñ– перезапуÑтити" @@ -7307,9 +7305,8 @@ msgid "This operation requires a single selected node." msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” одного обраного вузла." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Auto Orthogonal Enabled" -msgstr "Ортогонально" +msgstr "Увімкнено автоматичну ортогоналізацію" #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" @@ -9934,6 +9931,13 @@ msgstr "" "Зараз проєктів немає.\n" "Хочете вивчити проєкти офіційних прикладів з бібліотеки даних?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "Клавіша " @@ -10927,6 +10931,8 @@ msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." msgstr "" +"ЗауваженнÑ: Ð´Ð»Ñ Ð²Ð±ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ… Ñкриптів передбачено певні Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ â€” Ñ—Ñ… не " +"можна редагувати у зовнішньому редакторі." #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11049,6 +11055,11 @@ msgid "Total:" msgstr "Загалом:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "ЕкÑпорт профілю" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "ШлÑÑ… до реÑурÑу" @@ -12728,6 +12739,8 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." msgstr "" +"Щоб програма могла хоч щоÑÑŒ показати, розмір Ð¿Ð¾Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду має бути більшим " +"за 0." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 1e2f87b352..432a8d1137 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -9746,6 +9746,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10851,6 +10858,10 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 88ca61847e..a52a3dedf3 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -9866,6 +9866,13 @@ msgstr "" "Hiện giá» bạn không có project nà o.\n" "Bạn có muốn xem các project official và dụ trên Asset Library không?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -10997,6 +11004,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "Xuất hồ sÆ¡" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index df8b8e1725..953ec63714 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -64,8 +64,8 @@ msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2020-04-05 12:05+0000\n" -"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" +"PO-Revision-Date: 2020-04-24 15:30+0000\n" +"Last-Translator: Revan Ji <jiruifancr@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -73,7 +73,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.0-dev\n" +"X-Generator: Weblate 4.0.2-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2919,13 +2919,12 @@ msgid "Q&A" msgstr "é—®ç”" #: editor/editor_node.cpp -#, fuzzy msgid "Report a Bug" -msgstr "é‡æ–°å¯¼å…¥" +msgstr "报告问题" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "å‘é€æ–‡æ¡£å馈" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3962,9 +3961,8 @@ msgid "Reimport" msgstr "é‡æ–°å¯¼å…¥" #: editor/import_dock.cpp -#, fuzzy msgid "Save Scenes, Re-Import, and Restart" -msgstr "ä¿å˜åœºæ™¯ï¼Œé‡æ–°å¯¼å…¥ï¼Œä»Žå¤´å¼€å§‹" +msgstr "ä¿å˜åœºæ™¯ã€é‡æ–°å¯¼å…¥ï¼Œç„¶åŽé‡å¯" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -5681,7 +5679,7 @@ msgstr "从åƒç´ æ•èŽ·" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "Emission Colors(å‘射颜色)" +msgstr "Emission Colors(自å‘光颜色)" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" @@ -9770,6 +9768,13 @@ msgstr "" "ä½ ç›®å‰æ²¡æœ‰ä»»ä½•é¡¹ç›®ã€‚ \n" "是å¦æŸ¥çœ‹ç´ æ库ä¸çš„官方示例项目?" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "é”® " @@ -10746,7 +10751,7 @@ msgstr "脚本文件已å˜åœ¨ã€‚" msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." -msgstr "" +msgstr "注æ„:内置脚本有其局é™æ€§ï¼Œå¹¶ä¸”ä¸èƒ½ä½¿ç”¨å¤–部编辑器编辑。" #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -10869,6 +10874,11 @@ msgid "Total:" msgstr "åˆè®¡:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "导出é…置文件" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "资æºè·¯å¾„" @@ -12439,7 +12449,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "Viewport size must be greater than 0 to render anything." -msgstr "" +msgstr "Viewport大å°å¤§äºŽ0æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。" #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 31306885ae..e3d9a84cfb 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -10230,6 +10230,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11390,6 +11397,11 @@ msgid "Total:" msgstr "" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "匯出" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 235ce0d023..6b3651b5f6 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -10218,6 +10218,13 @@ msgid "" "Would you like to explore official example projects in the Asset Library?" msgstr "" +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + #: editor/project_settings_editor.cpp msgid "Key " msgstr "" @@ -11375,6 +11382,11 @@ msgid "Total:" msgstr "總計:" #: editor/script_editor_debugger.cpp +#, fuzzy +msgid "Export list to a CSV file" +msgstr "輸出專案" + +#: editor/script_editor_debugger.cpp msgid "Resource Path" msgstr "資æºè·¯å¾‘" diff --git a/main/main.cpp b/main/main.cpp index c625a9cb36..dff7907e72 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -32,7 +32,7 @@ #include "core/crypto/crypto.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" @@ -55,6 +55,7 @@ #include "main/splash.gen.h" #include "main/splash_editor.gen.h" #include "main/tests/test_main.h" +#include "modules/modules_enabled.gen.h" #include "modules/register_module_types.h" #include "platform/register_platform_apis.h" #include "scene/main/scene_tree.h" @@ -89,7 +90,7 @@ // Initialized in setup() static Engine *engine = nullptr; static ProjectSettings *globals = nullptr; -static InputFilter *input = nullptr; +static Input *input = nullptr; static InputMap *input_map = nullptr; static TranslationServer *translation_server = nullptr; static Performance *performance = nullptr; @@ -1162,9 +1163,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater")); GLOBAL_DEF("debug/settings/stdout/print_fps", false); + GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); - if (!OS::get_singleton()->_verbose_stdout) //overridden - OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); + if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden. + OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout"); + } if (frame_delay == 0) { frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0); @@ -1246,7 +1249,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { /* Initialize Input */ - input = memnew(InputFilter); + input = memnew(Input); /* Iniitalize Display Server */ @@ -1400,7 +1403,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { GLOBAL_DEF("application/config/windows_native_icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon", PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico")); - InputFilter *id = InputFilter::get_singleton(); + Input *id = Input::get_singleton(); if (id) { if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) { @@ -1435,7 +1438,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { Ref<Texture2D> cursor = ResourceLoader::load(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")); if (cursor.is_valid()) { Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot"); - InputFilter::get_singleton()->set_custom_mouse_cursor(cursor, InputFilter::CURSOR_ARROW, hotspot); + Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot); } } #ifdef TOOLS_ENABLED @@ -1597,6 +1600,19 @@ bool Main::start() { DirAccessRef da = DirAccess::open(doc_tool); ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory."); } + +#ifndef MODULE_MONO_ENABLED + // Hack to define Mono-specific project settings even on non-Mono builds, + // so that we don't lose their descriptions and default values in DocData. + // Default values should be synced with mono_gd/gd_mono.cpp. + GLOBAL_DEF("mono/debugger_agent/port", 23685); + GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false); + GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000); + GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd"); + GLOBAL_DEF("mono/profiler/enabled", false); + GLOBAL_DEF("mono/unhandled_exception_policy", 0); +#endif + DocData doc; doc.generate(doc_base); diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html index 6c6a3a5d2d..e7a23b3f29 100644 --- a/misc/dist/html/fixed-size.html +++ b/misc/dist/html/fixed-size.html @@ -3,7 +3,7 @@ <head> <meta charset="utf-8" /> <link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' /> - <title></title> + <title>$GODOT_PROJECT_NAME</title> <style type="text/css"> body { diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html index 92b65257d4..193f2a6aad 100644 --- a/misc/dist/html/full-size.html +++ b/misc/dist/html/full-size.html @@ -4,7 +4,7 @@ <meta charset='utf-8' /> <meta name='viewport' content='width=device-width, user-scalable=no' /> <link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' /> - <title></title> + <title>$GODOT_PROJECT_NAME</title> <style type='text/css'> body { diff --git a/misc/hooks/pre-commit-black b/misc/hooks/pre-commit-black index 2dcc2e8cf1..76d97294da 100755 --- a/misc/hooks/pre-commit-black +++ b/misc/hooks/pre-commit-black @@ -6,7 +6,7 @@ ################################################################## # SETTINGS # Set path to black binary. -BLACK=`which black` +BLACK=`which black 2>/dev/null` BLACK_OPTIONS="-l 120" # Remove any older patches from previous commits. Set to true or false. @@ -18,13 +18,22 @@ FILE_EXTS="py" # Use pygmentize instead of cat to parse diff with highlighting. # Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac) -PYGMENTIZE=`which pygmentize` +PYGMENTIZE=`which pygmentize 2>/dev/null` if [ ! -z "$PYGMENTIZE" ]; then READER="pygmentize -l diff" else READER=cat fi +# Path to zenity +ZENITY=`which zenity 2>/dev/null` + +# Path to xmessage +XMSG=`which xmessage 2>/dev/null` + +# Path to powershell (Windows only) +PWSH=`which powershell 2>/dev/null` + ################################################################## # There should be no need to change anything below this line. @@ -53,6 +62,19 @@ else fi if [ ! -x "$BLACK" ] ; then + if [ ! -t 1 ] ; then + if [ -x "$ZENITY" ] ; then + $ZENITY --error --title="Error" --text="Error: black executable not found." + exit 1 + elif [ -x "$XMSG" ] ; then + $XMSG -center -title "Error" "Error: black executable not found." + exit 1 + elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then + winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")" + $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: black executable not found." + exit 1 + fi + fi printf "Error: black executable not found.\n" printf "Set the correct path in $(canonicalize_filename "$0").\n" exit 1 @@ -99,14 +121,62 @@ fi # a patch has been created, notify the user and exit printf "\nThe following differences were found between the code to commit " printf "and the black formatter rules:\n\n" -$READER "$patch" -printf "\n" -# Allows us to read user input below, assigns stdin to keyboard -exec < /dev/tty +if [ -t 1 ] ; then + $READER "$patch" + printf "\n" + # Allows us to read user input below, assigns stdin to keyboard + exec < /dev/tty + terminal="1" +else + cat "$patch" + printf "\n" + # Allows non zero zenity/powershell output + set +e + terminal="0" +fi while true; do - read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn + if [ $terminal = "0" ] ; then + if [ -x "$ZENITY" ] ; then + ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage") + if [ "$?" = "0" ] ; then + yn="Y" + else + if [ "$ans" = "Apply and stage" ] ; then + yn="S" + else + yn="N" + fi + fi + elif [ -x "$XMSG" ] ; then + $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?" + ans=$? + if [ "$ans" = "100" ] ; then + yn="Y" + elif [ "$ans" = "200" ] ; then + yn="S" + else + yn="N" + fi + elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then + winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")" + $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?" + ans=$? + if [ "$ans" = "100" ] ; then + yn="Y" + elif [ "$ans" = "200" ] ; then + yn="S" + else + yn="N" + fi + else + printf "Error: zenity, xmessage, or powershell executable not found.\n" + exit 1 + fi + else + read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn + fi case $yn in [Yy] ) git apply $patch; printf "The patch was applied. You can now stage the changes and commit again.\n\n"; diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index c5cf4ecbb1..4e1fbdeb20 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -16,7 +16,7 @@ ################################################################## # SETTINGS # Set path to clang-format binary. -CLANG_FORMAT=`which clang-format` +CLANG_FORMAT=`which clang-format 2>/dev/null` # Remove any older patches from previous commits. Set to true or false. DELETE_OLD_PATCHES=false @@ -31,13 +31,22 @@ FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl" # Use pygmentize instead of cat to parse diff with highlighting. # Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac) -PYGMENTIZE=`which pygmentize` +PYGMENTIZE=`which pygmentize 2>/dev/null` if [ ! -z "$PYGMENTIZE" ]; then READER="pygmentize -l diff" else READER=cat fi +# Path to zenity +ZENITY=`which zenity 2>/dev/null` + +# Path to xmessage +XMSG=`which xmessage 2>/dev/null` + +# Path to powershell (Windows only) +PWSH=`which powershell 2>/dev/null` + ################################################################## # There should be no need to change anything below this line. @@ -66,6 +75,19 @@ else fi if [ ! -x "$CLANG_FORMAT" ] ; then + if [ ! -t 1 ] ; then + if [ -x "$ZENITY" ] ; then + $ZENITY --error --title="Error" --text="Error: clang-format executable not found." + exit 1 + elif [ -x "$XMSG" ] ; then + $XMSG -center -title "Error" "Error: clang-format executable not found." + exit 1 + elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then + winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")" + $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: clang-format executable not found." + exit 1 + fi + fi printf "Error: clang-format executable not found.\n" printf "Set the correct path in $(canonicalize_filename "$0").\n" exit 1 @@ -117,14 +139,62 @@ fi # a patch has been created, notify the user and exit printf "\nThe following differences were found between the code to commit " printf "and the clang-format rules:\n\n" -$READER "$patch" -printf "\n" -# Allows us to read user input below, assigns stdin to keyboard -exec < /dev/tty +if [ -t 1 ] ; then + $READER "$patch" + printf "\n" + # Allows us to read user input below, assigns stdin to keyboard + exec < /dev/tty + terminal="1" +else + cat "$patch" + printf "\n" + # Allows non zero zenity/powershell output + set +e + terminal="0" +fi while true; do - read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn + if [ $terminal = "0" ] ; then + if [ -x "$ZENITY" ] ; then + ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage") + if [ "$?" = "0" ] ; then + yn="Y" + else + if [ "$ans" = "Apply and stage" ] ; then + yn="S" + else + yn="N" + fi + fi + elif [ -x "$XMSG" ] ; then + $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?" + ans=$? + if [ "$ans" = "100" ] ; then + yn="Y" + elif [ "$ans" = "200" ] ; then + yn="S" + else + yn="N" + fi + elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then + winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")" + $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?" + ans=$? + if [ "$ans" = "100" ] ; then + yn="Y" + elif [ "$ans" = "200" ] ; then + yn="S" + else + yn="N" + fi + else + printf "Error: zenity, xmessage, or powershell executable not found.\n" + exit 1 + fi + else + read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn + fi case $yn in [Yy] ) git apply $patch; printf "The patch was applied. You can now stage the changes and commit again.\n\n"; diff --git a/misc/hooks/winmessage.ps1 b/misc/hooks/winmessage.ps1 new file mode 100755 index 0000000000..3672579544 --- /dev/null +++ b/misc/hooks/winmessage.ps1 @@ -0,0 +1,103 @@ +Param ( + [string]$file = "", + [string]$text = "", + [string]$buttons = "OK:0", + [string]$default = "", + [switch]$nearmouse = $false, + [switch]$center = $false, + [string]$geometry = "", + [int32]$timeout = 0, + [string]$title = "Message" +) +Add-Type -assembly System.Windows.Forms + +$global:Result = 0 + +$main_form = New-Object System.Windows.Forms.Form +$main_form.Text = $title + +$geometry_data = $geometry.Split("+") +if ($geometry_data.Length -ge 1) { + $size_data = $geometry_data[0].Split("x") + if ($size_data.Length -eq 2) { + $main_form.Width = $size_data[0] + $main_form.Height = $size_data[1] + } +} +if ($geometry_data.Length -eq 3) { + $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual + $main_form.Location = New-Object System.Drawing.Point($geometry_data[1], $geometry_data[2]) +} +if ($nearmouse) { + $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual + $main_form.Location = System.Windows.Forms.Cursor.Position +} +if ($center) { + $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen +} + +$main_form.SuspendLayout() + +$button_panel = New-Object System.Windows.Forms.FlowLayoutPanel +$button_panel.SuspendLayout() +$button_panel.FlowDirection = [System.Windows.Forms.FlowDirection]::RightToLeft +$button_panel.Dock = [System.Windows.Forms.DockStyle]::Bottom +$button_panel.Autosize = $true + +if ($file -ne "") { + $text = [IO.File]::ReadAllText($file).replace("`n", "`r`n") +} + +if ($text -ne "") { + $text_box = New-Object System.Windows.Forms.TextBox + $text_box.Multiline = $true + $text_box.ReadOnly = $true + $text_box.Autosize = $true + $text_box.Text = $text + $text_box.Select(0,0) + $text_box.Dock = [System.Windows.Forms.DockStyle]::Fill + $main_form.Controls.Add($text_box) +} + +$buttons_array = $buttons.Split(",") +foreach ($button in $buttons_array) { + $button_data = $button.Split(":") + $button_ctl = New-Object System.Windows.Forms.Button + if ($button_data.Length -eq 2) { + $button_ctl.Tag = $button_data[1] + } else { + $button_ctl.Tag = 100 + $buttons_array.IndexOf($button) + } + if ($default -eq $button_data[0]) { + $main_form.AcceptButton = $button_ctl + } + $button_ctl.Autosize = $true + $button_ctl.Text = $button_data[0] + $button_ctl.Add_Click( + { + Param($sender) + $global:Result = $sender.Tag + $main_form.Close() + } + ) + $button_panel.Controls.Add($button_ctl) +} +$main_form.Controls.Add($button_panel) + +$button_panel.ResumeLayout($false) +$main_form.ResumeLayout($false) + +if ($timeout -gt 0) { + $timer = New-Object System.Windows.Forms.Timer + $timer.Add_Tick( + { + $global:Result = 0 + $main_form.Close() + } + ) + $timer.Interval = $timeout + $timer.Start() +} +$dlg_res = $main_form.ShowDialog() + +[Environment]::Exit($global:Result) diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm index 79f09e2a7e..7de824815a 100644 --- a/modules/arkit/arkit_interface.mm +++ b/modules/arkit/arkit_interface.mm @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "scene/resources/surface_tool.h" #include "servers/rendering/rendering_server_globals.h" diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub index 692c749886..b853ebfc63 100644 --- a/modules/bullet/SCsub +++ b/modules/bullet/SCsub @@ -175,6 +175,7 @@ if env["builtin_bullet"]: "BulletSoftBody/btDeformableContactProjection.cpp", "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp", "BulletSoftBody/btDeformableContactConstraint.cpp", + "BulletSoftBody/poly34.cpp", # clew "clew/clew.c", # LinearMath @@ -203,6 +204,8 @@ if env["builtin_bullet"]: # if env['target'] == "debug" or env['target'] == "release_debug": # env_bullet.Append(CPPDEFINES=['BT_DEBUG']) + env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD"]) + env_thirdparty = env_bullet.Clone() env_thirdparty.disable_warnings() env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) diff --git a/modules/bullet/config.py b/modules/bullet/config.py index e8ca273f61..d22f9454ed 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -4,14 +4,3 @@ def can_build(env, platform): def configure(env): pass - - -def get_doc_classes(): - return [ - "BulletPhysicsDirectBodyState3D", - "BulletPhysicsServer3D", - ] - - -def get_doc_path(): - return "doc_classes" diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml deleted file mode 100644 index 1c0181bd9c..0000000000 --- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsDirectBodyState3D" inherits="PhysicsDirectBodyState3D" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index a4f9affa95..e393396713 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -503,15 +503,18 @@ void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p } case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: linearDamp = p_value; - btBody->setDamping(linearDamp, angularDamp); + // Mark for updating total linear damping. + scratch_space_override_modificator(); break; case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: angularDamp = p_value; - btBody->setDamping(linearDamp, angularDamp); + // Mark for updating total angular damping. + scratch_space_override_modificator(); break; case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: gravity_scale = p_value; - /// The Bullet gravity will be is set by reload_space_override_modificator + // The Bullet gravity will be is set by reload_space_override_modificator. + // Mark for updating total gravity scale. scratch_space_override_modificator(); break; default: @@ -902,21 +905,20 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { } void RigidBodyBullet::reload_space_override_modificator() { - // Make sure that kinematic bodies have their total gravity calculated if (!is_active() && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) return; - Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude()); - real_t newLinearDamp(linearDamp); - real_t newAngularDamp(angularDamp); + Vector3 newGravity(0.0, 0.0, 0.0); + real_t newLinearDamp = MAX(0.0, linearDamp); + real_t newAngularDamp = MAX(0.0, angularDamp); AreaBullet *currentArea; // Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer Vector3 support_gravity(0, 0, 0); - int countCombined(0); - for (int i = areaWhereIamCount - 1; 0 <= i; --i) { + bool stopped = false; + for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) { currentArea = areasWhereIam[i]; @@ -965,7 +967,6 @@ void RigidBodyBullet::reload_space_override_modificator() { newGravity += support_gravity; newLinearDamp += currentArea->get_spOv_linearDamp(); newAngularDamp += currentArea->get_spOv_angularDamp(); - ++countCombined; break; case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: /// This area adds its gravity/damp values to whatever has been calculated @@ -974,32 +975,31 @@ void RigidBodyBullet::reload_space_override_modificator() { newGravity += support_gravity; newLinearDamp += currentArea->get_spOv_linearDamp(); newAngularDamp += currentArea->get_spOv_angularDamp(); - ++countCombined; - goto endAreasCycle; + stopped = true; + break; case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: /// This area replaces any gravity/damp, even the default one, and /// stops taking into account the rest of the areas. newGravity = support_gravity; newLinearDamp = currentArea->get_spOv_linearDamp(); newAngularDamp = currentArea->get_spOv_angularDamp(); - countCombined = 1; - goto endAreasCycle; + stopped = true; + break; case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: /// This area replaces any gravity/damp calculated so far, but keeps /// calculating the rest of the areas, down to the default one. newGravity = support_gravity; newLinearDamp = currentArea->get_spOv_linearDamp(); newAngularDamp = currentArea->get_spOv_angularDamp(); - countCombined = 1; break; } } -endAreasCycle: - if (1 < countCombined) { - newGravity /= countCombined; - newLinearDamp /= countCombined; - newAngularDamp /= countCombined; + // Add default gravity and damping from space. + if (!stopped) { + newGravity += space->get_gravity_direction() * space->get_gravity_magnitude(); + newLinearDamp += space->get_linear_damp(); + newAngularDamp += space->get_angular_damp(); } btVector3 newBtGravity; diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 1659664ff9..d49e635fd5 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -342,6 +342,8 @@ SpaceBullet::SpaceBullet() : godotFilterCallback(nullptr), gravityDirection(0, -1, 0), gravityMagnitude(10), + linear_damp(0.0), + angular_damp(0.0), contactDebugCount(0), delta_time(0.) { @@ -379,8 +381,11 @@ void SpaceBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Varian update_gravity(); break; case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: + linear_damp = p_value; + break; case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - break; // No damp + angular_damp = p_value; + break; case PhysicsServer3D::AREA_PARAM_PRIORITY: // Priority is always 0, the lower break; @@ -401,8 +406,9 @@ Variant SpaceBullet::get_param(PhysicsServer3D::AreaParameter p_param) { case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: return gravityDirection; case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: + return linear_damp; case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: - return 0; // No damp + return angular_damp; case PhysicsServer3D::AREA_PARAM_PRIORITY: return 0; // Priority is always 0, the lower case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index f9a8c063fd..3d4a2aeceb 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -108,6 +108,9 @@ class SpaceBullet : public RIDBullet { Vector3 gravityDirection; real_t gravityMagnitude; + real_t linear_damp; + real_t angular_damp; + Vector<AreaBullet *> areas; Vector<Vector3> contactDebug; @@ -177,6 +180,9 @@ public: void update_gravity(); + real_t get_linear_damp() const { return linear_damp; } + real_t get_angular_damp() const { return angular_damp; } + bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes); int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 5557da3014..d38ddf3f90 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -296,20 +296,18 @@ void CSGShape3D::_update_shape() { int mat = n->faces[i].material; ERR_CONTINUE(mat < -1 || mat >= face_count.size()); int idx = mat == -1 ? face_count.size() - 1 : mat; - if (n->faces[i].smooth) { - Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); + Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]); - for (int j = 0; j < 3; j++) { - Vector3 v = n->faces[i].vertices[j]; - Vector3 add; - if (vec_map.lookup(v, add)) { - add += p.normal; - } else { - add = p.normal; - } - vec_map.set(v, add); + for (int j = 0; j < 3; j++) { + Vector3 v = n->faces[i].vertices[j]; + Vector3 add; + if (vec_map.lookup(v, add)) { + add += p.normal; + } else { + add = p.normal; } + vec_map.set(v, add); } face_count.write[idx]++; diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index ae21156b8b..294d594135 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 5b89f16277..ef08967df7 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index ad0cc91c96..bfb2098dff 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -42,7 +42,7 @@ struct ETC1Header { uint16_t origHeight; }; -RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h index 989e203994..6507e0bdec 100644 --- a/modules/etc/texture_loader_pkm.h +++ b/modules/etc/texture_loader_pkm.h @@ -36,7 +36,7 @@ class ResourceFormatPKM : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index d3426044ec..a131e3a78f 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -493,7 +493,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_ return result; } -RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { Ref<GDNativeLibrary> lib; lib.instance(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 9ef9c706d1..6d26c2141d 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -166,7 +166,7 @@ public: class GDNativeLibraryResourceLoader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index dcf2ddb9ca..0fb5180103 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -95,6 +95,7 @@ typedef enum { GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor GODOT_PROPERTY_USAGE_CATEGORY = 256, + GODOT_PROPERTY_USAGE_SUBGROUP = 512, GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048, GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096, GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192, diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index bf458c15ee..ed3ec44bf7 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -111,6 +111,13 @@ void NativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) #endif +bool NativeScript::inherits_script(const Ref<Script> &p_script) const { +#ifndef _MSC_VER +#warning inheritance needs to be implemented in NativeScript +#endif + return false; +} + void NativeScript::set_class_name(String p_class_name) { class_name = p_class_name; } @@ -1931,7 +1938,7 @@ void NativeReloadNode::_notification(int p_what) { #endif } -RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 75bbb42664..7e7598e06c 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -133,6 +133,8 @@ protected: public: inline NativeScriptDesc *get_script_desc() const; + bool inherits_script(const Ref<Script> &p_script) const; + void set_class_name(String p_class_name); String get_class_name() const; @@ -406,7 +408,7 @@ public: class ResourceFormatLoaderNativeScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index 3fb22b3f8d..64582cc517 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL _language = language; } -RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index c929be53bd..e47754490a 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -44,7 +44,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader { public: ResourceFormatLoaderPluginScript(PluginScriptLanguage *language); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index a4c84dc0ca..6b303c8716 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -140,6 +140,13 @@ bool PluginScript::can_instance() const { return can; } +bool PluginScript::inherits_script(const Ref<Script> &p_script) const { +#ifndef _MSC_VER +#warning inheritance needs to be implemented in PluginScript +#endif + return false; +} + Ref<Script> PluginScript::get_base_script() const { if (_ref_base_parent.is_valid()) { return Ref<PluginScript>(_ref_base_parent); diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 5c93ae38f5..70b9ca980b 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -72,6 +72,8 @@ private: protected: static void _bind_methods(); + bool inherits_script(const Ref<Script> &p_script) const; + PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error); Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index fa9f6be5c1..f7d87595af 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -373,7 +373,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) { /* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */ -RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index fbc0d4016f..092e10a0f5 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -199,7 +199,7 @@ public: class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp index 0451945139..d65089a123 100644 --- a/modules/gdnative/xr/xr_interface_gdnative.cpp +++ b/modules/gdnative/xr/xr_interface_gdnative.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "xr_interface_gdnative.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "servers/rendering/rendering_server_globals.h" #include "servers/xr/xr_positional_tracker.h" @@ -306,7 +306,7 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 0); - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); ERR_FAIL_NULL_V(input, 0); XRPositionalTracker *new_tracker = memnew(XRPositionalTracker); @@ -345,7 +345,7 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); ERR_FAIL_NULL(input); XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); @@ -383,7 +383,7 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); ERR_FAIL_NULL(input); XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); @@ -399,14 +399,14 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); ERR_FAIL_NULL(input); XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker != nullptr) { int joyid = tracker->get_joy_id(); if (joyid != -1) { - InputFilter::JoyAxis jx; + Input::JoyAxis jx; jx.min = p_can_be_negative ? -1 : 0; jx.value = p_value; input->joy_axis(joyid, p_axis, jx); diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py index 185a10bcb2..6fc227e7f5 100644 --- a/modules/gdscript/config.py +++ b/modules/gdscript/config.py @@ -11,7 +11,6 @@ def get_doc_classes(): "@GDScript", "GDScript", "GDScriptFunctionState", - "GDScriptNativeClass", ] diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml deleted file mode 100644 index 0a8982de8e..0000000000 --- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="GDScriptNativeClass" inherits="Reference" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - <method name="new"> - <return type="Variant"> - </return> - <description> - </description> - </method> - </methods> - <constants> - </constants> -</class> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 9a4fa5cc86..98366f7957 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -895,6 +895,24 @@ Ref<GDScript> GDScript::get_base() const { return base; } +bool GDScript::inherits_script(const Ref<Script> &p_script) const { + Ref<GDScript> gd = p_script; + if (gd.is_null()) { + return false; + } + + const GDScript *s = this; + + while (s) { + if (s == p_script.ptr()) { + return true; + } + s = s->_base; + } + + return false; +} + bool GDScript::has_script_signal(const StringName &p_signal) const { if (_signals.has(p_signal)) return true; @@ -2257,7 +2275,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 2c5876372b..5fdc25669f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -151,6 +151,8 @@ protected: public: virtual bool is_valid() const { return valid; } + bool inherits_script(const Ref<Script> &p_script) const; + const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; } const Map<StringName, Variant> &get_constants() const { return constants; } const Set<StringName> &get_members() const { return members; } @@ -545,7 +547,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 2ec3352e70..7ad0682637 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2057,7 +2057,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<PropertyInfo> pinfo; ClassDB::get_property_list(type, &pinfo); for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) { + if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) { continue; } if (E->get().name.find("/") != -1) { @@ -2098,7 +2098,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (!p_only_functions) { List<PropertyInfo> members; - p_base.value.get_property_list(&members); + tmp.get_property_list(&members); for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { if (String(E->get().name).find("/") == -1) { @@ -2150,7 +2150,7 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p } const GDScriptParser::ClassNode *clss = p_context._class; - bool _static = !p_context.function || p_context.function->_static; + bool _static = p_context.function && p_context.function->_static; while (clss) { GDScriptCompletionContext c = p_context; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index ca4d6f6de9..4e0891921e 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -337,15 +337,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (!argument_types[i].is_type(*p_args[i], true)) { - if (argument_types[i].is_type(Variant(), true)) { - memnew_placement(&stack[i], Variant); - continue; - } else { - r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_err.argument = i; - r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT; - return Variant(); - } + r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_err.argument = i; + r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT; + return Variant(); } if (argument_types[i].kind == GDScriptDataType::BUILTIN) { Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 8d34ce5c70..411512d631 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -746,6 +746,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) { _make_completable_call(0); completion_node = op; + + if (op->arguments[0]->type == GDScriptParser::Node::Type::TYPE_BUILT_IN_FUNCTION) { + BuiltInFunctionNode *bn = static_cast<BuiltInFunctionNode *>(op->arguments[0]); + if (bn->function == GDScriptFunctions::Function::RESOURCE_LOAD) { + completion_type = COMPLETION_RESOURCE_PATH; + } + } } if (!replaced) { if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) @@ -827,6 +834,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s //check from singletons ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier]; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -837,6 +845,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (scr.is_valid() && scr->is_valid()) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = scr; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -852,6 +861,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (parent_constants.has(identifier)) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = parent_constants[identifier]; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -2022,6 +2032,38 @@ GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_paren return expr; } +bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) { + + if (p_value.get_type() == Variant::ARRAY) { + Array arr = p_value; + for (int i = 0; i < arr.size(); i++) { + if (!_reduce_export_var_type(arr[i], p_line)) return false; + } + return true; + } + + if (p_value.get_type() == Variant::DICTIONARY) { + Dictionary dict = p_value; + for (int i = 0; i < dict.size(); i++) { + Variant value = dict.get_value_at_index(i); + if (!_reduce_export_var_type(value, p_line)) return false; + } + return true; + } + + // validate type + DataType type = _type_from_variant(p_value); + if (type.kind == DataType::BUILTIN) { + return true; + } else if (type.kind == DataType::NATIVE) { + if (ClassDB::is_parent_class(type.native_type, "Resource")) { + return true; + } + } + _set_error("Invalid export type. Only built-in and native resource types can be exported.", p_line); + return false; +} + bool GDScriptParser::_recover_from_completion() { if (!completion_found) { @@ -2386,6 +2428,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // a bind always matches ConstantNode *true_value = alloc_node<ConstantNode>(); true_value->value = Variant(true); + true_value->datatype = _type_from_variant(true_value->value); p_resulting_node = true_value; } break; case PatternNode::PT_ARRAY: { @@ -2432,6 +2475,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // size ConstantNode *length = alloc_node<ConstantNode>(); length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size()); + length->datatype = _type_from_variant(length->value); OperatorNode *call = alloc_node<OperatorNode>(); call->op = OperatorNode::OP_CALL; @@ -2465,6 +2509,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m ConstantNode *index = alloc_node<ConstantNode>(); index->value = Variant(i); + index->datatype = _type_from_variant(index->value); OperatorNode *indexed_value = alloc_node<OperatorNode>(); indexed_value->op = OperatorNode::OP_INDEX; @@ -2525,6 +2570,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // size ConstantNode *length = alloc_node<ConstantNode>(); length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size()); + length->datatype = _type_from_variant(length->value); OperatorNode *call = alloc_node<OperatorNode>(); call->op = OperatorNode::OP_CALL; @@ -2601,6 +2647,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // simply generate a `true` ConstantNode *true_value = alloc_node<ConstantNode>(); true_value->value = Variant(true); + true_value->datatype = _type_from_variant(true_value->value); p_resulting_node = true_value; } break; default: { @@ -2683,6 +2730,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) { LocalVarNode *local_var = branch->body->variables[e->key()]; local_var->assign = e->value(); local_var->set_datatype(local_var->assign->get_datatype()); + local_var->assignments++; IdentifierNode *id2 = alloc_node<IdentifierNode>(); id2->name = local_var->name; @@ -2785,6 +2833,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { return; } + _mark_line_as_safe(line); NewLineNode *nl2 = alloc_node<NewLineNode>(); nl2->line = line; p_block->statements.push_back(nl2); @@ -3298,6 +3347,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { return; } + int assert_line = tokenizer->get_token_line(); + tokenizer->advance(); Vector<Node *> args; @@ -3311,14 +3362,21 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { return; } +#ifdef DEBUG_ENABLED + // Mark as safe, let type check mark as unsafe if needed + _mark_line_as_safe(assert_line); + _reduce_node_type(args[0]); +#endif AssertNode *an = alloc_node<AssertNode>(); an->condition = _reduce_expression(args[0], p_static); + an->line = assert_line; if (args.size() == 2) { an->message = _reduce_expression(args[1], p_static); } else { ConstantNode *message_node = alloc_node<ConstantNode>(); message_node->value = String(); + message_node->datatype = _type_from_variant(message_node->value); an->message = message_node; } @@ -3673,6 +3731,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ")."); return; } + for (int i = 0; i < outer_class->variables.size(); i++) { + if (outer_class->variables[i].identifier == name) { + _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ")."); + return; + } + } outer_class = outer_class->owner; } @@ -4863,6 +4927,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _set_error("Can't accept a null constant expression for inferring export type."); return; } + + if (!_reduce_export_var_type(cn->value, member.line)) return; + member._export.type = cn->value.get_type(); member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; if (cn->value.get_type() == Variant::OBJECT) { @@ -6229,11 +6296,13 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType ConstantNode *c = alloc_node<ConstantNode>(); Callable::CallError err; c->value = Variant::construct(p_type.builtin_type, nullptr, 0, err); + c->datatype = _type_from_variant(c->value); result = c; } } else { ConstantNode *c = alloc_node<ConstantNode>(); c->value = Variant(); + c->datatype = _type_from_variant(c->value); result = c; } @@ -6562,6 +6631,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true); #ifdef DEBUG_ENABLED if (!node_type.has_type) { + _mark_line_as_unsafe(op->line); _add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string()); } #endif // DEBUG_ENABLED @@ -7364,7 +7434,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN } } -#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))) +#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY))) // Check other script types while (scr.is_valid()) { @@ -8110,6 +8180,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { ConstantNode *tgt_type = alloc_node<ConstantNode>(); tgt_type->line = lv->line; tgt_type->value = (int)lv->datatype.builtin_type; + tgt_type->datatype = _type_from_variant(tgt_type->value); OperatorNode *convert_call = alloc_node<OperatorNode>(); convert_call->line = lv->line; @@ -8245,6 +8316,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { ConstantNode *tgt_type = alloc_node<ConstantNode>(); tgt_type->line = op->line; tgt_type->value = (int)lh_type.builtin_type; + tgt_type->datatype = _type_from_variant(tgt_type->value); OperatorNode *convert_call = alloc_node<OperatorNode>(); convert_call->line = op->line; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index eca5f83f7a..f254352423 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -613,6 +613,7 @@ private: Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false); Node *_reduce_expression(Node *p_node, bool p_to_const = false); Node *_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const = false, bool p_allow_assign = false); + bool _reduce_export_var_type(Variant &p_value, int p_line = 0); PatternNode *_parse_pattern(bool p_static); void _parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index eb8feb5bc7..9c3101945a 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "grid_map_editor_plugin.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/node_3d_editor_plugin.h" diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 2f0a15f20b..48276c0d3d 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -29,7 +29,8 @@ /*************************************************************************/ #include "mobile_vr_interface.h" -#include "core/input/input_filter.h" + +#include "core/input/input.h" #include "core/os/os.h" #include "servers/display_server.h" #include "servers/rendering/rendering_server_globals.h" @@ -118,7 +119,7 @@ void MobileVRInterface::set_position_from_sensors() { float delta_time = (double)ticks_elapsed / 1000000.0; // few things we need - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); Vector3 down(0.0, -1.0, 0.0); // Down is Y negative Vector3 north(0.0, 0.0, 1.0); // North is Z positive diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 0b5d3c8dbc..f5911275c9 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3536,6 +3536,18 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { } } +bool CSharpScript::inherits_script(const Ref<Script> &p_script) const { + Ref<CSharpScript> cs = p_script; + if (cs.is_null()) { + return false; + } + +#ifndef _MSC_VER +#warning TODO: Implement CSharpScript::inherits_script and other relevant changes after GH-38063. +#endif + return false; +} + Ref<Script> CSharpScript::get_base_script() const { // TODO search in metadata file once we have it, not important any way? @@ -3673,7 +3685,7 @@ CSharpScript::~CSharpScript() { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 29c33b50bb..05e2857538 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -194,6 +194,8 @@ public: virtual bool is_tool() const { return tool; } virtual bool is_valid() const { return valid; } + bool inherits_script(const Ref<Script> &p_script) const; + virtual Ref<Script> get_base_script() const; virtual ScriptLanguage *get_language() const; @@ -530,7 +532,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs new file mode 100644 index 0000000000..85760a3705 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs @@ -0,0 +1,27 @@ +using System.IO; + +namespace GodotTools.Core +{ + public static class FileUtils + { + public static void SaveBackupCopy(string filePath) + { + string backupPathBase = filePath + ".old"; + string backupPath = backupPathBase; + + const int maxAttempts = 5; + int attempt = 1; + + while (File.Exists(backupPath) && attempt <= maxAttempts) + { + backupPath = backupPathBase + "." + (attempt); + attempt++; + } + + if (attempt > maxAttempts + 1) + return; + + File.Copy(filePath, backupPath, overwrite: true); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj index 2c35ef540a..c9ea7d3a2c 100644 --- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj +++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj @@ -31,6 +31,7 @@ <Reference Include="System" /> </ItemGroup> <ItemGroup> + <Compile Include="FileUtils.cs" /> <Compile Include="ProcessExtensions.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="StringExtensions.cs" /> diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index 9afd9adeb1..6f318aab4a 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -153,7 +153,12 @@ EndProject"; var result = regex.Replace(input,m => dict[m.Value]); if (result != input) + { + // Save a copy of the solution before replacing it + FileUtils.SaveBackupCopy(slnPath); + File.WriteAllText(slnPath, result); + } } } } diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs index 1776b46e6a..f2ebef1a7d 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -9,8 +9,28 @@ using Microsoft.Build.Construction; namespace GodotTools.ProjectEditor { + public sealed class MSBuildProject + { + public ProjectRootElement Root { get; } + + public bool HasUnsavedChanges { get; set; } + + public void Save() => Root.Save(); + + public MSBuildProject(ProjectRootElement root) + { + Root = root; + } + } + public static class ProjectUtils { + public static MSBuildProject Open(string path) + { + var root = ProjectRootElement.Open(path); + return root != null ? new MSBuildProject(root) : null; + } + public static void AddItemToProjectChecked(string projectPath, string itemType, string include) { var dir = Directory.GetParent(projectPath).FullName; @@ -43,7 +63,6 @@ namespace GodotTools.ProjectEditor public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include) { - var dir = Directory.GetParent(projectPath).FullName; var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); @@ -150,12 +169,9 @@ namespace GodotTools.ProjectEditor } /// Simple function to make sure the Api assembly references are configured correctly - public static void FixApiHintPath(string projectPath) + public static void FixApiHintPath(MSBuildProject project) { - var root = ProjectRootElement.Open(projectPath); - Debug.Assert(root != null); - - bool dirty = false; + var root = project.Root; void AddPropertyIfNotPresent(string name, string condition, string value) { @@ -170,7 +186,7 @@ namespace GodotTools.ProjectEditor } root.AddProperty(name, value).Condition = " " + condition + " "; - dirty = true; + project.HasUnsavedChanges = true; } AddPropertyIfNotPresent(name: "ApiConfiguration", @@ -212,7 +228,7 @@ namespace GodotTools.ProjectEditor } referenceWithHintPath.AddMetadata("HintPath", hintPath); - dirty = true; + project.HasUnsavedChanges = true; return; } @@ -221,14 +237,14 @@ namespace GodotTools.ProjectEditor { // Found a Reference item without a HintPath referenceWithoutHintPath.AddMetadata("HintPath", hintPath); - dirty = true; + project.HasUnsavedChanges = true; return; } } // Found no Reference item at all. Add it. root.AddItem("Reference", referenceName).Condition = " " + condition + " "; - dirty = true; + project.HasUnsavedChanges = true; } const string coreProjectName = "GodotSharp"; @@ -242,17 +258,11 @@ namespace GodotTools.ProjectEditor SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath); SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath); - - if (dirty) - root.Save(); } - public static void MigrateFromOldConfigNames(string projectPath) + public static void MigrateFromOldConfigNames(MSBuildProject project) { - var root = ProjectRootElement.Open(projectPath); - Debug.Assert(root != null); - - bool dirty = false; + var root = project.Root; bool hasGodotProjectGeneratorVersion = false; bool foundOldConfiguration = false; @@ -267,7 +277,7 @@ namespace GodotTools.ProjectEditor { configItem.Value = "Debug"; foundOldConfiguration = true; - dirty = true; + project.HasUnsavedChanges = true; } } @@ -275,7 +285,7 @@ namespace GodotTools.ProjectEditor { root.PropertyGroups.First(g => g.Condition == string.Empty)? .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - dirty = true; + project.HasUnsavedChanges = true; } if (!foundOldConfiguration) @@ -301,7 +311,7 @@ namespace GodotTools.ProjectEditor foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition)) { propertyGroup.Condition = " " + newCondition + " "; - dirty = true; + project.HasUnsavedChanges = true; } foreach (var propertyGroup in root.PropertyGroups) @@ -309,14 +319,14 @@ namespace GodotTools.ProjectEditor foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition)) { prop.Condition = " " + newCondition + " "; - dirty = true; + project.HasUnsavedChanges = true; } } foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition)) { itemGroup.Condition = " " + newCondition + " "; - dirty = true; + project.HasUnsavedChanges = true; } foreach (var itemGroup in root.ItemGroups) @@ -324,7 +334,7 @@ namespace GodotTools.ProjectEditor foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition)) { item.Condition = " " + newCondition + " "; - dirty = true; + project.HasUnsavedChanges = true; } } } @@ -340,10 +350,6 @@ namespace GodotTools.ProjectEditor MigrateConfigurationConditions("Release", "ExportRelease"); MigrateConfigurationConditions("Tools", "Debug"); // Must be last } - - - if (dirty) - root.Save(); } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index d782d4e61b..2ceb4888a2 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -168,13 +168,13 @@ namespace GodotTools.Export // Add dependency assemblies - var dependencies = new Godot.Collections.Dictionary<string, string>(); + var assemblies = new Godot.Collections.Dictionary<string, string>(); string projectDllName = GodotSharpEditor.ProjectAssemblyName; string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig); string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll"); - dependencies[projectDllName] = projectDllSrcPath; + assemblies[projectDllName] = projectDllSrcPath; if (platform == OS.Platforms.Android) { @@ -184,15 +184,15 @@ namespace GodotTools.Export if (!File.Exists(monoAndroidAssemblyPath)) throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath); - dependencies["Mono.Android"] = monoAndroidAssemblyPath; + assemblies["Mono.Android"] = monoAndroidAssemblyPath; } string bclDir = DeterminePlatformBclDir(platform); - var initialDependencies = dependencies.Duplicate(); - internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, bclDir, dependencies); + var initialAssemblies = assemblies.Duplicate(); + internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies); - AddI18NAssemblies(dependencies, bclDir); + AddI18NAssemblies(assemblies, bclDir); string outputDataDir = null; @@ -211,20 +211,32 @@ namespace GodotTools.Export Directory.CreateDirectory(outputDataGameAssembliesDir); } - foreach (var dependency in dependencies) + foreach (var assembly in assemblies) { - string dependSrcPath = dependency.Value; - - if (assembliesInsidePck) - { - string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile()); - AddFile(dependSrcPath, dependDstPath); - } - else + void AddToAssembliesDir(string fileSrcPath) { - string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile()); - File.Copy(dependSrcPath, dependDstPath); + if (assembliesInsidePck) + { + string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile()); + AddFile(fileSrcPath, fileDstPath); + } + else + { + Debug.Assert(outputDataDir != null); + string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile()); + File.Copy(fileSrcPath, fileDstPath); + } } + + string assemblySrcPath = assembly.Value; + + string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null); + string pdbSrcPath = assemblyPathWithoutExtension + ".pdb"; + + AddToAssembliesDir(assemblySrcPath); + + if (File.Exists(pdbSrcPath)) + AddToAssembliesDir(pdbSrcPath); } // AOT compilation @@ -254,7 +266,7 @@ namespace GodotTools.Export ToolchainPath = aotToolchainPath }; - AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, dependencies); + AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies); } } @@ -366,7 +378,7 @@ namespace GodotTools.Export if (PlatformRequiresCustomBcl(platform)) throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}"); - platformBclDir = typeof(object).Assembly.Location; // Use the one we're running on + platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on } } @@ -425,7 +437,7 @@ namespace GodotTools.Export } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies, - string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies); + private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies, + string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index c9d7dd26f8..c070cb16d9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -1,4 +1,5 @@ using Godot; +using GodotTools.Core; using GodotTools.Export; using GodotTools.Utils; using System; @@ -442,13 +443,27 @@ namespace GodotTools { // Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath); + + var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath) + ?? throw new Exception("Cannot open C# project"); + + // NOTE: The order in which changes are made to the project is important + // Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease - ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath); + ProjectUtils.MigrateFromOldConfigNames(msbuildProject); - // Apply the other fixes after configurations are migrated + // Apply the other fixes only after configurations have been migrated // Make sure the existing project has Api assembly references configured correctly - ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); + ProjectUtils.FixApiHintPath(msbuildProject); + + if (msbuildProject.HasUnsavedChanges) + { + // Save a copy of the project before replacing it + FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath); + + msbuildProject.Save(); + } } catch (Exception e) { diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 71bb8ff851..ee92a6234a 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2383,7 +2383,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { const PropertyInfo &property = E->get(); - if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_CATEGORY) + if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) continue; PropertyInterface iprop; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 283d4beb8e..c3e7e67ae9 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -231,14 +231,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje return err; } -uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies, - MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) { - Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies); +uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies, + MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) { + Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies); String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config); String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir); - Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies); + Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies); - return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies); + return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies); } MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) { diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 324013e5e2..4126da16be 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -50,13 +50,13 @@ String get_assemblyref_name(MonoImage *p_image, int index) { return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME])); } -Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) { +Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { String ref_name = get_assemblyref_name(image, i); - if (r_dependencies.has(ref_name)) + if (r_assembly_dependencies.has(ref_name)) continue; GDMonoAssembly *ref_assembly = nullptr; @@ -93,17 +93,17 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'."); // Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir. - r_dependencies[ref_name] = path; + r_assembly_dependencies[ref_name] = path; - Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); + Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'."); } return OK; } -Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies, - const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) { +Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies, + const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) { MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport"); ERR_FAIL_NULL_V(export_domain, FAILED); _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); @@ -113,16 +113,16 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie Vector<String> search_dirs; GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir); - for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) { + for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) { String assembly_name = *key; - String assembly_path = p_initial_dependencies[*key]; + String assembly_path = p_initial_assemblies[*key]; GDMonoAssembly *assembly = nullptr; bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true); ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'."); - Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies); + Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies); if (err != OK) return err; } diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 36138f81b7..9ab57755de 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -41,8 +41,8 @@ namespace GodotSharpExport { Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies); -Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies, - const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies); +Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies, + const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies); } // namespace GodotSharpExport diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index aba1065498..a963810d63 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -15,10 +15,7 @@ namespace Godot.Collections public override bool IsInvalid { - get - { - return handle == IntPtr.Zero; - } + get { return handle == IntPtr.Zero; } } protected override bool ReleaseHandle() @@ -43,7 +40,8 @@ namespace Godot.Collections if (collection == null) throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'"); - MarshalUtils.EnumerableToArray(collection, GetPtr()); + foreach (object element in collection) + Add(element); } internal Array(ArraySafeHandle handle) @@ -272,14 +270,8 @@ namespace Godot.Collections public T this[int index] { - get - { - return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); - } - set - { - objectArray[index] = value; - } + get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); } + set { objectArray[index] = value; } } public int IndexOf(T item) @@ -301,18 +293,12 @@ namespace Godot.Collections public int Count { - get - { - return objectArray.Count; - } + get { return objectArray.Count; } } public bool IsReadOnly { - get - { - return objectArray.IsReadOnly; - } + get { return objectArray.IsReadOnly; } } public void Add(T item) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index d72109de92..213fc181c1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -15,10 +15,7 @@ namespace Godot.Collections public override bool IsInvalid { - get - { - return handle == IntPtr.Zero; - } + get { return handle == IntPtr.Zero; } } protected override bool ReleaseHandle() @@ -45,7 +42,8 @@ namespace Godot.Collections if (dictionary == null) throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'"); - MarshalUtils.IDictionaryToDictionary(dictionary, GetPtr()); + foreach (DictionaryEntry entry in dictionary) + Add(entry.Key, entry.Value); } internal Dictionary(DictionarySafeHandle handle) @@ -330,14 +328,8 @@ namespace Godot.Collections public TValue this[TKey key] { - get - { - return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); - } - set - { - objectDict[key] = value; - } + get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); } + set { objectDict[key] = value; } } public ICollection<TKey> Keys @@ -385,18 +377,12 @@ namespace Godot.Collections public int Count { - get - { - return objectDict.Count; - } + get { return objectDict.Count; } } public bool IsReadOnly { - get - { - return objectDict.IsReadOnly; - } + get { return objectDict.IsReadOnly; } } public void Add(KeyValuePair<TKey, TValue> item) @@ -440,7 +426,8 @@ namespace Godot.Collections public bool Remove(KeyValuePair<TKey, TValue> item) { - return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ; + return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); + ; } // IEnumerable<KeyValuePair<TKey, TValue>> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs index a1d63a62ef..c59d083080 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs @@ -16,10 +16,8 @@ namespace Godot /// <exception cref="System.InvalidOperationException"> /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false. /// </exception> - static bool TypeIsGenericArray(Type type) - { - return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>); - } + static bool TypeIsGenericArray(Type type) => + type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>); /// <summary> /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/> @@ -28,10 +26,20 @@ namespace Godot /// <exception cref="System.InvalidOperationException"> /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false. /// </exception> - static bool TypeIsGenericDictionary(Type type) - { - return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>); - } + static bool TypeIsGenericDictionary(Type type) => + type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>); + + static bool TypeIsSystemGenericList(Type type) => + type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>); + + static bool TypeIsSystemGenericDictionary(Type type) => + type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>); + + static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>); + + static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>); static void ArrayGetElementType(Type arrayType, out Type elementType) { @@ -45,105 +53,6 @@ namespace Godot valueType = genericArgs[1]; } - static bool GenericIEnumerableIsAssignableFromType(Type type) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - return true; - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - return true; - } - - Type baseType = type.BaseType; - - if (baseType == null) - return false; - - return GenericIEnumerableIsAssignableFromType(baseType); - } - - static bool GenericIDictionaryIsAssignableFromType(Type type) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - return true; - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - return true; - } - - Type baseType = type.BaseType; - - if (baseType == null) - return false; - - return GenericIDictionaryIsAssignableFromType(baseType); - } - - static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - elementType = type.GetGenericArguments()[0]; - return true; - } - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - elementType = interfaceType.GetGenericArguments()[0]; - return true; - } - } - - Type baseType = type.BaseType; - - if (baseType == null) - { - elementType = null; - return false; - } - - return GenericIEnumerableIsAssignableFromType(baseType, out elementType); - } - - static bool GenericIDictionaryIsAssignableFromType(Type type, out Type keyType, out Type valueType) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - { - var genericArgs = type.GetGenericArguments(); - keyType = genericArgs[0]; - valueType = genericArgs[1]; - return true; - } - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - { - var genericArgs = interfaceType.GetGenericArguments(); - keyType = genericArgs[0]; - valueType = genericArgs[1]; - return true; - } - } - - Type baseType = type.BaseType; - - if (baseType == null) - { - keyType = null; - valueType = null; - return false; - } - - return GenericIDictionaryIsAssignableFromType(baseType, out keyType, out valueType); - } - static Type MakeGenericArrayType(Type elemType) { return typeof(Godot.Collections.Array<>).MakeGenericType(elemType); @@ -153,60 +62,5 @@ namespace Godot { return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType); } - - // TODO Add support for IEnumerable<T> and IDictionary<TKey, TValue> - // TODO: EnumerableToArray and IDictionaryToDictionary can be optimized - - internal static void EnumerableToArray(IEnumerable enumerable, IntPtr godotArrayPtr) - { - if (enumerable is ICollection collection) - { - int count = collection.Count; - - object[] tempArray = new object[count]; - collection.CopyTo(tempArray, 0); - - for (int i = 0; i < count; i++) - { - Array.godot_icall_Array_Add(godotArrayPtr, tempArray[i]); - } - } - else - { - foreach (object element in enumerable) - { - Array.godot_icall_Array_Add(godotArrayPtr, element); - } - } - } - - internal static void IDictionaryToDictionary(IDictionary dictionary, IntPtr godotDictionaryPtr) - { - foreach (DictionaryEntry entry in dictionary) - { - Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, entry.Key, entry.Value); - } - } - - internal static void GenericIDictionaryToDictionary(object dictionary, IntPtr godotDictionaryPtr) - { -#if DEBUG - if (!GenericIDictionaryIsAssignableFromType(dictionary.GetType())) - throw new InvalidOperationException("The type does not implement IDictionary<,>"); -#endif - - // TODO: Can we optimize this? - - var keys = ((IEnumerable)dictionary.GetType().GetProperty("Keys").GetValue(dictionary)).GetEnumerator(); - var values = ((IEnumerable)dictionary.GetType().GetProperty("Values").GetValue(dictionary)).GetEnumerator(); - - while (keys.MoveNext() && values.MoveNext()) - { - object key = keys.Current; - object value = values.Current; - - Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, key, value); - } - } } } diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index fe8b925257..d596163926 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -40,7 +40,7 @@ #endif #ifdef ANDROID_ENABLED -#include "mono_gd/support/mono-support.h" +#include "mono_gd/support/android_support.h" #endif #include "mono_gd/gd_mono.h" diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 306a1997ab..3298c5da4c 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -129,12 +129,8 @@ void gd_mono_profiler_init() { } } -#if defined(DEBUG_ENABLED) - void gd_mono_debug_init() { - mono_debug_init(MONO_DEBUG_FORMAT_MONO); - CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); #ifdef TOOLS_ENABLED @@ -159,6 +155,10 @@ void gd_mono_debug_init() { return; // Exported games don't use the project settings to setup the debugger agent #endif + // Debugging enabled + + mono_debug_init(MONO_DEBUG_FORMAT_MONO); + // --debugger-agent=help const char *options[] = { "--soft-breakpoints", @@ -167,7 +167,6 @@ void gd_mono_debug_init() { mono_jit_parse_options(2, (char **)options); } -#endif // defined(DEBUG_ENABLED) #endif // !defined(JAVASCRIPT_ENABLED) #if defined(JAVASCRIPT_ENABLED) @@ -175,6 +174,7 @@ MonoDomain *gd_initialize_mono_runtime() { const char *vfs_prefix = "managed"; int enable_debugging = 0; + // TODO: Provide a way to enable debugging on WASM release builds. #ifdef DEBUG_ENABLED enable_debugging = 1; #endif @@ -185,9 +185,7 @@ MonoDomain *gd_initialize_mono_runtime() { } #else MonoDomain *gd_initialize_mono_runtime() { -#ifdef DEBUG_ENABLED gd_mono_debug_init(); -#endif #if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED) // I don't know whether this actually matters or not @@ -1389,7 +1387,10 @@ bool _GodotSharp::is_runtime_initialized() { void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD - CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); + // This method may be called more than once with `call_deferred`, so we need to check + // again if reloading is needed to avoid reloading multiple times unnecessarily. + if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) + CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); #endif } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 8439769d84..0f211eebc6 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -277,12 +277,25 @@ no_pdb: #endif + bool need_manual_load_hook = mono_image_get_assembly(image) != nullptr; // Re-using an existing image with an assembly loaded + status = MONO_IMAGE_OK; MonoAssembly *assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, p_refonly); ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !assembly, nullptr, "Failed to load assembly for image"); + if (need_manual_load_hook) { + // For some reason if an assembly survived domain reloading (maybe because it's referenced somewhere else), + // the mono internal search hook don't detect it, yet mono_image_open_from_data_with_name re-uses the image + // and assembly, and mono_assembly_load_from_full doesn't call the load hook. We need to call it manually. + String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly))); + bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); + GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); + if (!loaded_asm) + assembly_load_hook(assembly, nullptr); + } + // Decrement refcount which was previously incremented by mono_image_open_from_data_with_name mono_image_close(image); diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index facc0da780..5ddf18d544 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -84,6 +84,7 @@ void CachedData::clear_corlib_cache() { class_IntPtr = nullptr; class_System_Collections_IEnumerable = nullptr; + class_System_Collections_ICollection = nullptr; class_System_Collections_IDictionary = nullptr; #ifdef DEBUG_ENABLED @@ -171,22 +172,18 @@ void CachedData::clear_godot_api_cache() { methodthunk_MarshalUtils_TypeIsGenericArray.nullify(); methodthunk_MarshalUtils_TypeIsGenericDictionary.nullify(); + methodthunk_MarshalUtils_TypeIsSystemGenericList.nullify(); + methodthunk_MarshalUtils_TypeIsSystemGenericDictionary.nullify(); + methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify(); + methodthunk_MarshalUtils_TypeIsGenericICollection.nullify(); + methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify(); methodthunk_MarshalUtils_ArrayGetElementType.nullify(); methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify(); - methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType.nullify(); - methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info.nullify(); - methodthunk_MarshalUtils_MakeGenericArrayType.nullify(); methodthunk_MarshalUtils_MakeGenericDictionaryType.nullify(); - methodthunk_MarshalUtils_EnumerableToArray.nullify(); - methodthunk_MarshalUtils_IDictionaryToDictionary.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryToDictionary.nullify(); - // End of MarshalUtils methods task_scheduler_handle = Ref<MonoGCHandleRef>(); @@ -213,6 +210,7 @@ void update_corlib_cache() { CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class())); CACHE_CLASS_AND_CHECK(System_Collections_IEnumerable, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IEnumerable")); + CACHE_CLASS_AND_CHECK(System_Collections_ICollection, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "ICollection")); CACHE_CLASS_AND_CHECK(System_Collections_IDictionary, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IDictionary")); #ifdef DEBUG_ENABLED @@ -297,22 +295,18 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericList, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericList", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 1)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 1)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 3)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericArrayType", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericDictionaryType", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, EnumerableToArray, GODOT_API_CLASS(MarshalUtils)->get_method("EnumerableToArray", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("IDictionaryToDictionary", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryToDictionary", 2)); - // End of MarshalUtils methods #ifdef DEBUG_ENABLED diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 21c8ed4efe..3cf2bd6ce5 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -58,6 +58,7 @@ struct CachedData { GDMonoClass *class_IntPtr; // System.IntPtr GDMonoClass *class_System_Collections_IEnumerable; + GDMonoClass *class_System_Collections_ICollection; GDMonoClass *class_System_Collections_IDictionary; #ifdef DEBUG_ENABLED @@ -141,22 +142,18 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericDictionary; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericList; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericDictionary; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info; - GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericArrayType; GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericDictionaryType; - GDMonoMethodThunk<MonoObject *, Array *> methodthunk_MarshalUtils_EnumerableToArray; - GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_IDictionaryToDictionary; - GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_GenericIDictionaryToDictionary; - // End of MarshalUtils methods Ref<MonoGCHandleRef> task_scheduler_handle; @@ -186,14 +183,6 @@ inline void clear_godot_api_cache() { cached_data.clear_godot_api_cache(); } -_FORCE_INLINE_ bool tools_godot_api_check() { -#ifdef TOOLS_ENABLED - return cached_data.godot_api_cache_updated; -#else - return true; // Assume it's updated if this was called, otherwise it's a bug -#endif -} - } // namespace GDMonoCache #define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class) diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index ede4203e35..2c65f7e3a0 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -31,6 +31,7 @@ #include "gd_mono_class.h" #include <mono/metadata/attrdefs.h> +#include <mono/metadata/debug-helpers.h> #include "gd_mono_assembly.h" #include "gd_mono_cache.h" @@ -55,7 +56,11 @@ String GDMonoClass::get_full_name() const { return get_full_name(mono_class); } -MonoType *GDMonoClass::get_mono_type() { +String GDMonoClass::get_type_desc() const { + return GDMonoUtils::get_type_desc(get_mono_type()); +} + +MonoType *GDMonoClass::get_mono_type() const { // Careful, you cannot compare two MonoType*. // There is mono_metadata_type_equal, how is this different from comparing two MonoClass*? return get_mono_type(mono_class); @@ -264,6 +269,12 @@ bool GDMonoClass::implements_interface(GDMonoClass *p_interface) { return mono_class_implements_interface(mono_class, p_interface->get_mono_ptr()); } +bool GDMonoClass::has_public_parameterless_ctor() { + + GDMonoMethod *ctor = get_method(".ctor", 0); + return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC; +} + GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) { MethodKey key = MethodKey(p_name, p_params_count); @@ -328,6 +339,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); mono_method_desc_free(desc); + if (!method) + return nullptr; + ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr); return get_method(method); diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 0c9a8cdafe..9237aae057 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -31,8 +31,6 @@ #ifndef GD_MONO_CLASS_H #define GD_MONO_CLASS_H -#include <mono/metadata/debug-helpers.h> - #include "core/map.h" #include "core/ustring.h" @@ -107,7 +105,8 @@ public: static MonoType *get_mono_type(MonoClass *p_mono_class); String get_full_name() const; - MonoType *get_mono_type(); + String get_type_desc() const; + MonoType *get_mono_type() const; uint32_t get_flags() const; bool is_static() const; @@ -137,6 +136,7 @@ public: void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base); bool implements_interface(GDMonoClass *p_interface); + bool has_public_parameterless_ctor(); GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0); GDMonoMethod *get_method(MonoMethod *p_raw_method); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 3f4e5fe5ac..e76cb84d43 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -322,6 +322,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { + MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class); + mono_field_set_value(p_object, mono_field, managed); + break; + } + ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -353,56 +360,22 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Dictionary or IDictionary + if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); mono_field_set_value(p_object, mono_field, managed); break; } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Array or ICollection or IEnumerable + if (CACHED_CLASS(Array) == type_class || + type_class == CACHED_CLASS(System_Collections_ICollection) || + type_class == CACHED_CLASS(System_Collections_IEnumerable)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); mono_field_set_value(p_object, mono_field, managed); break; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; - } else { - MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); - mono_field_set_value(p_object, mono_field, managed); - break; - } - } - ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'."); } break; @@ -535,52 +508,62 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(), + type.type_class, key_reftype, value_reftype); mono_field_set_value(p_object, mono_field, managed); break; } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(), + type.type_class, elem_reftype); mono_field_set_value(p_object, mono_field, managed); break; } - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + MonoReflectionType *key_reftype; + MonoReflectionType *value_reftype; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype); + + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class); mono_field_set_value(p_object, mono_field, managed); break; } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; - } else { - MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); - mono_field_set_value(p_object, mono_field, managed); - break; - } + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { + MonoReflectionType *elem_reftype; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype); + + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class); + mono_field_set_value(p_object, mono_field, managed); + break; } } break; diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 1878038f44..91ee07388b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -154,6 +154,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (array_type->eklass == CACHED_CLASS_RAW(Color)) return Variant::PACKED_COLOR_ARRAY; + + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return Variant::ARRAY; } break; case MONO_TYPE_CLASS: { @@ -184,23 +188,14 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ return Variant::ARRAY; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return Variant::DICTIONARY; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { + // IDictionary + if (p_type.type_class == CACHED_CLASS(System_Collections_IDictionary)) { return Variant::DICTIONARY; } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return Variant::ARRAY; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { + // ICollection or IEnumerable + if (p_type.type_class == CACHED_CLASS(System_Collections_ICollection) || + p_type.type_class == CACHED_CLASS(System_Collections_IEnumerable)) { return Variant::ARRAY; } } break; @@ -214,27 +209,33 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return Variant::DICTIONARY; } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { return Variant::ARRAY; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) - return Variant::DICTIONARY; - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { return Variant::DICTIONARY; } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { return Variant::ARRAY; + } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + return Variant::DICTIONARY; + } + + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { return Variant::ARRAY; } } break; @@ -252,10 +253,20 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) { switch (p_array_type.type_encoding) { + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: { + MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type()); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + r_elem_type = ManagedType::from_class(array_type_class); + return true; + } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type()); - if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) { + if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype) || + GDMonoUtils::Marshal::type_is_system_generic_list(array_reftype) || + GDMonoUtils::Marshal::type_is_generic_icollection(array_reftype) || + GDMonoUtils::Marshal::type_is_generic_ienumerable(array_reftype)) { MonoReflectionType *elem_reftype; GDMonoUtils::Marshal::array_get_element_type(array_reftype, &elem_reftype); @@ -263,12 +274,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ r_elem_type = ManagedType::from_reftype(elem_reftype); return true; } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(array_reftype, &elem_reftype)) { - r_elem_type = ManagedType::from_reftype(elem_reftype); - return true; - } } break; default: { } break; @@ -282,7 +287,9 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma case MONO_TYPE_GENERICINST: { MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type()); - if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) { + if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) || + GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) || + GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) { MonoReflectionType *key_reftype; MonoReflectionType *value_reftype; @@ -292,13 +299,6 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma r_value_type = ManagedType::from_reftype(value_reftype); return true; } - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(dict_reftype, &key_reftype, &value_reftype)) { - r_key_type = ManagedType::from_reftype(key_reftype); - r_value_type = ManagedType::from_reftype(value_reftype); - return true; - } } break; default: { } break; @@ -577,6 +577,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty if (array_type->eklass == CACHED_CLASS_RAW(Color)) return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray()); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -600,41 +604,17 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::create_managed_from(p_var->operator RID()); } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Dictionary or IDictionary + if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Array or ICollection or IEnumerable + if (CACHED_CLASS(Array) == type_class || + CACHED_CLASS(System_Collections_ICollection) == type_class || + CACHED_CLASS(System_Collections_IEnumerable) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); } - - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); - } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); - } else { - return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); - } - } } break; case MONO_TYPE_OBJECT: { // Variant @@ -755,38 +735,48 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class); } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class); } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype); } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype); } - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + MonoReflectionType *key_reftype; + MonoReflectionType *value_reftype; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype); + + return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class); } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); - } else { - return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); - } + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { + MonoReflectionType *elem_reftype; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype); + + return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class); } } break; } break; @@ -922,6 +912,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type if (array_type->eklass == CACHED_CLASS_RAW(Color)) return mono_array_to_PackedColorArray((MonoArray *)p_obj); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return mono_array_to_Array((MonoArray *)p_obj); + if (p_fail_with_err) { ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); } else { @@ -957,44 +951,27 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return ptr ? Variant(*ptr) : Variant(); } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Dictionary + if (CACHED_CLASS(Dictionary) == type_class) { MonoException *exc = nullptr; - Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc); + Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Array + if (CACHED_CLASS(Array) == type_class) { MonoException *exc = nullptr; - Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc); + Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } - - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj); - } - - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoException *exc = nullptr; MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); @@ -1002,6 +979,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return *unbox<Dictionary *>(ret); } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoException *exc = nullptr; MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); @@ -1009,22 +987,19 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return *unbox<Array *>(ret); } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); - } - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + return system_generic_dict_to_Dictionary(p_obj, p_type.type_class, key_reftype, value_reftype); } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype); } } break; } @@ -1081,6 +1056,80 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { } } +MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(ctor == nullptr); + + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); + ERR_FAIL_NULL_V(mono_object, nullptr); + + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); + MonoObject *godot_dict = GDMonoUtils::create_managed_from(p_dict, godot_dict_class); + + void *ctor_args[1] = { godot_dict }; + + MonoException *exc = nullptr; + ctor->invoke_raw(mono_object, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_object; +} + +Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); + String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(godot_dict_ctor == nullptr); + + MonoObject *godot_dict = mono_object_new(mono_domain_get(), godot_dict_class->get_mono_ptr()); + ERR_FAIL_NULL_V(godot_dict, Dictionary()); + + void *ctor_args[1] = { p_obj }; + + MonoException *exc = nullptr; + godot_dict_ctor->invoke_raw(godot_dict, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + exc = nullptr; + MonoObject *ret = godot_dict_class->get_method("GetPtr")->invoke(godot_dict, &exc); + UNHANDLED_EXCEPTION(exc); + + return *unbox<Dictionary *>(ret); +} + +MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) { + GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class; + + String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)"; + GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(ctor == nullptr); + + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); + ERR_FAIL_NULL_V(mono_object, nullptr); + + void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) }; + + MonoException *exc = nullptr; + ctor->invoke_raw(mono_object, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_object; +} + +Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) { + GDMonoMethod *to_array = p_class->get_method("ToArray", 0); + CRASH_COND(to_array == nullptr); + + MonoException *exc = nullptr; + MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_array_to_Array(mono_array); +} + MonoArray *Array_to_mono_array(const Array &p_array) { int length = p_array.size(); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length); @@ -1093,6 +1142,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) { return ret; } +MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) { + int length = p_array.size(); + MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length); + + for (int i = 0; i < length; i++) { + MonoObject *boxed = variant_to_mono_object(p_array[i]); + mono_array_setref(ret, i, boxed); + } + + return ret; +} + Array mono_array_to_Array(MonoArray *p_array) { Array ret; if (!p_array) diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 8b405291a7..f2d887e6d6 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -123,9 +123,18 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_ty /// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead. String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc); +// System.Collections.Generic + +MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); +Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); + +MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); +Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); + // Array MonoArray *Array_to_mono_array(const Array &p_array); +MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class); Array mono_array_to_Array(MonoArray *p_array); // PackedInt32Array diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index c8cc5247c6..432aa74a6f 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -30,13 +30,14 @@ #include "gd_mono_method.h" +#include <mono/metadata/attrdefs.h> +#include <mono/metadata/debug-helpers.h> + #include "gd_mono_cache.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" #include "gd_mono_utils.h" -#include <mono/metadata/attrdefs.h> - void GDMonoMethod::_update_signature() { // Apparently MonoMethodSignature needs not to be freed. // mono_method_signature caches the result, we don't need to cache it ourselves. diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 00119ced88..f9d492dabb 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -30,6 +30,7 @@ #include "gd_mono_utils.h" +#include <mono/metadata/debug-helpers.h> #include <mono/metadata/exception.h> #include "core/debugger/engine_debugger.h" @@ -358,6 +359,14 @@ MonoDomain *create_domain(const String &p_friendly_name) { return domain; } +String get_type_desc(MonoType *p_type) { + return mono_type_full_name(p_type); +} + +String get_type_desc(MonoReflectionType *p_reftype) { + return get_type_desc(mono_reflection_type_get_type(p_reftype)); +} + String get_exception_name_and_message(MonoException *p_exc) { String res; @@ -584,75 +593,56 @@ bool type_is_generic_dictionary(MonoReflectionType *p_reftype) { return (bool)res; } -void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { - MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); - UNHANDLED_EXCEPTION(exc); -} - -void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { - MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc); - UNHANDLED_EXCEPTION(exc); -} - -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { +bool type_is_system_generic_list(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType).invoke(p_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericList).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { +bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType).invoke(p_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericDictionary).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { +bool type_is_generic_ienumerable(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info).invoke(p_reftype, r_elem_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIEnumerable).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { +bool type_is_generic_icollection(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info).invoke(p_reftype, r_key_reftype, r_value_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericICollection).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -Array enumerable_to_array(MonoObject *p_enumerable) { - NO_GLUE_RET(Array()); - Array result; +bool type_is_generic_idictionary(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray).invoke(p_enumerable, &result, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIDictionary).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; + return (bool)res; } -Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) { - NO_GLUE_RET(Dictionary()); - Dictionary result; +void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary).invoke(p_idictionary, &result, &exc); + CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; } -Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) { - NO_GLUE_RET(Dictionary()); - Dictionary result; +void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary).invoke(p_generic_idictionary, &result, &exc); + CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; } GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) { diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index b850e1be9b..e3011ade5d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -52,22 +52,18 @@ namespace Marshal { bool type_is_generic_array(MonoReflectionType *p_reftype); bool type_is_generic_dictionary(MonoReflectionType *p_reftype); +bool type_is_system_generic_list(MonoReflectionType *p_reftype); +bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype); +bool type_is_generic_ienumerable(MonoReflectionType *p_reftype); +bool type_is_generic_icollection(MonoReflectionType *p_reftype); +bool type_is_generic_idictionary(MonoReflectionType *p_reftype); void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype); void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype); -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype); -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype); -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); - GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype); GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); -Array enumerable_to_array(MonoObject *p_enumerable); -Dictionary idictionary_to_dictionary(MonoObject *p_idictionary); -Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary); - } // namespace Marshal _FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) { @@ -115,6 +111,9 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class); MonoDomain *create_domain(const String &p_friendly_name); +String get_type_desc(MonoType *p_type); +String get_type_desc(MonoReflectionType *p_reftype); + String get_exception_name_and_message(MonoException *p_exc); void set_exception_message(MonoException *p_exc, String message); diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 10d4d71f5e..a8e8a9a2f1 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -51,7 +51,7 @@ enum PVRFLags { }; -RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h index 642323db35..07ef129689 100644 --- a/modules/pvr/texture_loader_pvr.h +++ b/modules/pvr/texture_loader_pvr.h @@ -36,7 +36,7 @@ class ResourceFormatPVR : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index e5fb6f996d..b9f276fb12 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -725,7 +725,7 @@ void VideoStreamTheora::_bind_methods() { //////////// -RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index cd7bff7adb..f98368ed8b 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -187,7 +187,7 @@ public: class ResourceFormatLoaderTheora : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 7cc52eef36..fe1d82f977 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1460,6 +1460,10 @@ VisualScript::VisualScript() { is_tool_script = false; } +bool VisualScript::inherits_script(const Ref<Script> &p_script) const { + return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough +} + StringName VisualScript::get_default_func() const { return StringName("f_312843592"); } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 29309aa156..c154e56703 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -272,6 +272,8 @@ protected: static void _bind_methods(); public: + bool inherits_script(const Ref<Script> &p_script) const; + // TODO: Remove it in future when breaking changes are acceptable StringName get_default_func() const; void add_function(const StringName &p_name); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 59b1bcdd96..9a4076bec4 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -30,7 +30,7 @@ #include "visual_script_editor.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/object.h" #include "core/os/keyboard.h" #include "core/script_language.h" @@ -1073,9 +1073,9 @@ void VisualScriptEditor::_member_selected() { if (ti->get_parent() == members->get_root()->get_children()) { #ifdef OSX_ENABLED - bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_META); + bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); #endif if (held_ctrl) { ERR_FAIL_COND(!script->has_function(selected)); @@ -1378,7 +1378,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt } } else if (ti->get_parent() == root->get_children()) { selected = ti->get_text(0); - function_name_edit->set_position(InputFilter::get_singleton()->get_mouse_position() - Vector2(60, -10)); + function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10)); function_name_edit->popup(); function_name_box->set_text(selected); function_name_box->select_all(); @@ -1740,7 +1740,7 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> key = p_event; if (key.is_valid() && !key->is_pressed()) { - mouse_up_position = InputFilter::get_singleton()->get_mouse_position(); + mouse_up_position = Input::get_singleton()->get_mouse_position(); } } @@ -1750,7 +1750,7 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (key.is_valid() && key->is_pressed() && key->get_button_mask() == BUTTON_RIGHT) { saved_position = graph->get_local_mouse_position(); - Point2 gpos = InputFilter::get_singleton()->get_mouse_position(); + Point2 gpos = Input::get_singleton()->get_mouse_position(); _generic_search(script->get_instance_base_type(), gpos); } } @@ -2004,9 +2004,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "visual_script_variable_drag") { #ifdef OSX_ENABLED - bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_META); + bool use_set = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL); #endif Vector2 ofs = graph->get_scroll_ofs() + p_point; if (graph->is_using_snap()) { @@ -2199,9 +2199,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } #ifdef OSX_ENABLED - bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_META); + bool use_node = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL); #endif Array nodes = d["nodes"]; @@ -2263,7 +2263,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); - if (!sn && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name())); return; } @@ -2283,12 +2283,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da ofs /= EDSCALE; #ifdef OSX_ENABLED - bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_META); + bool use_get = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL); #endif - if (!node || InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { if (use_get) undo_redo->create_action(TTR("Add Getter Property")); diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 475893e86d..8a644c6860 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -934,6 +934,6 @@ void register_visual_script_flow_control_nodes() { VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>); VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>); VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>); - //VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>); + //VisualScriptLanguage::singleton->add_register_func("flow_control/input", create_node_generic<VisualScriptInputFilter>); VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>); } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index c860e08943..52399d29d0 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -32,7 +32,7 @@ #include "core/engine.h" #include "core/global_constants.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "scene/main/node.h" @@ -3870,16 +3870,16 @@ public: switch (mode) { case VisualScriptInputAction::MODE_PRESSED: { - *p_outputs[0] = InputFilter::get_singleton()->is_action_pressed(action); + *p_outputs[0] = Input::get_singleton()->is_action_pressed(action); } break; case VisualScriptInputAction::MODE_RELEASED: { - *p_outputs[0] = !InputFilter::get_singleton()->is_action_pressed(action); + *p_outputs[0] = !Input::get_singleton()->is_action_pressed(action); } break; case VisualScriptInputAction::MODE_JUST_PRESSED: { - *p_outputs[0] = InputFilter::get_singleton()->is_action_just_pressed(action); + *p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action); } break; case VisualScriptInputAction::MODE_JUST_RELEASED: { - *p_outputs[0] = InputFilter::get_singleton()->is_action_just_released(action); + *p_outputs[0] = Input::get_singleton()->is_action_just_released(action); } break; } diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index ca78d664f7..a2d0f78f5f 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -474,7 +474,7 @@ void VideoStreamWebm::set_audio_track(int p_track) { //////////// -RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index bc209e0057..6677fb85aa 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -128,7 +128,7 @@ public: class ResourceFormatLoaderWebm : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index e293dfd50c..8c5525bed3 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -32,14 +32,91 @@ #include "core/error_macros.h" +#include "core/crypto/crypto_core.h" + #include "thirdparty/xatlas/xatlas.h" #include <stdio.h> #include <stdlib.h> -extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y); +extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache); + +bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uvs, int **r_vertices, int *r_vertex_count, int **r_indices, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache) { + + CryptoCore::MD5Context ctx; + ctx.start(); + + ctx.update((unsigned char *)&p_texel_size, sizeof(float)); + ctx.update((unsigned char *)p_indices, sizeof(int) * p_index_count); + ctx.update((unsigned char *)p_vertices, sizeof(float) * p_vertex_count); + ctx.update((unsigned char *)p_normals, sizeof(float) * p_vertex_count); + + unsigned char hash[16]; + ctx.finish(hash); + + bool cached = false; + unsigned int cache_idx = 0; + + if (r_used_cache && r_cache_size) { + //Check if hash is in cache data + + int *cache_data = r_cache_data; + int n_entries = cache_data[0]; + unsigned int r_idx = 1; + for (int i = 0; i < n_entries; ++i) { + if (memcmp(&cache_data[r_idx], hash, 16) == 0) { + cached = true; + cache_idx = r_idx; + break; + } + + r_idx += 4; // hash + r_idx += 2; // size hint + + int vertex_count = cache_data[r_idx]; + r_idx += 1; // vertex count + r_idx += vertex_count; // vertex + r_idx += vertex_count * 2; // uvs + + int index_count = cache_data[r_idx]; + r_idx += 1; // index count + r_idx += index_count; // indices + } + } -bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) { + if (r_used_cache && cached) { + int *cache_data = r_cache_data; + + // Return cache data pointer to the caller + r_cache_data = &cache_data[cache_idx]; + + cache_idx += 4; + + // Load size + *r_size_hint_x = cache_data[cache_idx]; + *r_size_hint_y = cache_data[cache_idx + 1]; + cache_idx += 2; + + // Load vertices + *r_vertex_count = cache_data[cache_idx]; + cache_idx++; + *r_vertices = &cache_data[cache_idx]; + cache_idx += *r_vertex_count; + + // Load UVs + *r_uvs = (float *)&cache_data[cache_idx]; + cache_idx += *r_vertex_count * 2; + + // Load indices + *r_index_count = cache_data[cache_idx]; + cache_idx++; + *r_indices = &cache_data[cache_idx]; + + // Return cache data size to the caller + r_cache_size = sizeof(int) * (4 + 2 + 1 + *r_vertex_count + (*r_vertex_count * 2) + 1 + *r_index_count); // hash + size hint + vertex_count + vertices + uvs + index_count + indices + r_used_cache = true; + return true; + } //set up input mesh xatlas::MeshDecl input_mesh; @@ -82,16 +159,16 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver const xatlas::Mesh &output = atlas->meshes[0]; - *r_vertex = (int *)malloc(sizeof(int) * output.vertexCount); - *r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2); - *r_index = (int *)malloc(sizeof(int) * output.indexCount); + *r_vertices = (int *)malloc(sizeof(int) * output.vertexCount); + *r_uvs = (float *)malloc(sizeof(float) * output.vertexCount * 2); + *r_indices = (int *)malloc(sizeof(int) * output.indexCount); float max_x = 0; float max_y = 0; for (uint32_t i = 0; i < output.vertexCount; i++) { - (*r_vertex)[i] = output.vertexArray[i].xref; - (*r_uv)[i * 2 + 0] = output.vertexArray[i].uv[0] / w; - (*r_uv)[i * 2 + 1] = output.vertexArray[i].uv[1] / h; + (*r_vertices)[i] = output.vertexArray[i].xref; + (*r_uvs)[i * 2 + 0] = output.vertexArray[i].uv[0] / w; + (*r_uvs)[i * 2 + 1] = output.vertexArray[i].uv[1] / h; max_x = MAX(max_x, output.vertexArray[i].uv[0]); max_y = MAX(max_y, output.vertexArray[i].uv[1]); } @@ -100,13 +177,54 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver *r_vertex_count = output.vertexCount; for (uint32_t i = 0; i < output.indexCount; i++) { - (*r_index)[i] = output.indexArray[i]; + (*r_indices)[i] = output.indexArray[i]; } *r_index_count = output.indexCount; xatlas::Destroy(atlas); - printf("Done\n"); + + if (r_used_cache) { + unsigned int new_cache_size = 4 + 2 + 1 + *r_vertex_count + (*r_vertex_count * 2) + 1 + *r_index_count; // hash + size hint + vertex_count + vertices + uvs + index_count + indices + new_cache_size *= sizeof(int); + int *new_cache_data = (int *)memalloc(new_cache_size); + unsigned int new_cache_idx = 0; + + // hash + memcpy(&new_cache_data[new_cache_idx], hash, 16); + new_cache_idx += 4; + + // size hint + new_cache_data[new_cache_idx] = *r_size_hint_x; + new_cache_data[new_cache_idx + 1] = *r_size_hint_y; + new_cache_idx += 2; + + // vertex count + new_cache_data[new_cache_idx] = *r_vertex_count; + new_cache_idx++; + + // vertices + memcpy(&new_cache_data[new_cache_idx], *r_vertices, sizeof(int) * *r_vertex_count); + new_cache_idx += *r_vertex_count; + + // uvs + memcpy(&new_cache_data[new_cache_idx], *r_uvs, sizeof(float) * *r_vertex_count * 2); + new_cache_idx += *r_vertex_count * 2; + + // index count + new_cache_data[new_cache_idx] = *r_index_count; + new_cache_idx++; + + // indices + memcpy(&new_cache_data[new_cache_idx], *r_indices, sizeof(int) * *r_index_count); + new_cache_idx += *r_index_count; + + // Return cache data to the caller + r_cache_data = new_cache_data; + r_cache_size = new_cache_size; + r_used_cache = false; + } + return true; } diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 9534387d35..60d10b2457 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -424,7 +424,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis } #endif - InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events); + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); } DisplayServerAndroid::~DisplayServerAndroid() { @@ -445,16 +445,16 @@ DisplayServerAndroid::~DisplayServerAndroid() { void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) { switch (p_event.type) { case JOY_EVENT_BUTTON: - InputFilter::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed); + Input::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed); break; case JOY_EVENT_AXIS: - InputFilter::JoyAxis value; + Input::JoyAxis value; value.min = -1; value.value = p_event.value; - InputFilter::get_singleton()->joy_axis(p_event.device, p_event.index, value); + Input::get_singleton()->joy_axis(p_event.device, p_event.index, value); break; case JOY_EVENT_HAT: - InputFilter::get_singleton()->joy_hat(p_event.device, p_event.hat); + Input::get_singleton()->joy_hat(p_event.device, p_event.hat); break; default: return; @@ -484,7 +484,7 @@ void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int OS_Android::get_singleton()->main_loop_request_go_back(); } - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) { @@ -499,7 +499,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(touch[i].id); ev->set_pressed(false); ev->set_position(touch[i].pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } } @@ -517,7 +517,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(touch[i].id); ev->set_pressed(true); ev->set_position(touch[i].pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } } break; @@ -545,7 +545,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(touch[i].id); ev->set_position(p_points[idx].pos); ev->set_relative(p_points[idx].pos - touch[i].pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); touch.write[i].pos = p_points[idx].pos; } @@ -560,7 +560,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(touch[i].id); ev->set_pressed(false); ev->set_position(touch[i].pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } touch.clear(); } @@ -577,7 +577,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(tp.id); ev->set_pressed(true); ev->set_position(tp.pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); break; } @@ -592,7 +592,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector ev->set_index(touch[i].id); ev->set_pressed(false); ev->set_position(touch[i].pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); touch.remove(i); break; @@ -613,7 +613,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) { ev->set_position(p_pos); ev->set_global_position(p_pos); ev->set_relative(p_pos - hover_prev_pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); hover_prev_pos = p_pos; } break; } @@ -626,7 +626,7 @@ void DisplayServerAndroid::process_double_tap(Point2 p_pos) { ev->set_global_position(p_pos); ev->set_pressed(false); ev->set_doubleclick(true); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } void DisplayServerAndroid::process_scroll(Point2 p_pos) { @@ -634,22 +634,22 @@ void DisplayServerAndroid::process_scroll(Point2 p_pos) { ev.instance(); ev->set_position(p_pos); ev->set_delta(p_pos - scroll_prev_pos); - InputFilter::get_singleton()->parse_input_event(ev); + Input::get_singleton()->parse_input_event(ev); scroll_prev_pos = p_pos; } void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) { - InputFilter::get_singleton()->set_accelerometer(p_accelerometer); + Input::get_singleton()->set_accelerometer(p_accelerometer); } void DisplayServerAndroid::process_gravity(const Vector3 &p_gravity) { - InputFilter::get_singleton()->set_gravity(p_gravity); + Input::get_singleton()->set_gravity(p_gravity); } void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) { - InputFilter::get_singleton()->set_magnetometer(p_magnetometer); + Input::get_singleton()->set_magnetometer(p_magnetometer); } void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) { - InputFilter::get_singleton()->set_gyroscope(p_gyroscope); + Input::get_singleton()->set_gyroscope(p_gyroscope); } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 1eb1ee0d29..d4fc52eaa9 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1179,14 +1179,32 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static String _parse_string(const uint8_t *p_bytes, bool p_utf8) { uint32_t offset = 0; - uint32_t len = decode_uint16(&p_bytes[offset]); + uint32_t len = 0; if (p_utf8) { - //don't know how to read extended utf8, this will have to be for now - len >>= 8; + uint8_t byte = p_bytes[offset]; + if (byte & 0x80) + offset += 2; + else + offset += 1; + byte = p_bytes[offset]; + offset++; + if (byte & 0x80) { + len = byte & 0x7F; + len = (len << 8) + p_bytes[offset]; + offset++; + } else { + len = byte; + } + } else { + len = decode_uint16(&p_bytes[offset]); + offset += 2; + if (len & 0x8000) { + len &= 0x7FFF; + len = (len << 16) + decode_uint16(&p_bytes[offset]); + offset += 2; + } } - offset += 2; - //printf("len %i, unicode: %i\n",len,int(p_utf8)); if (p_utf8) { @@ -1699,7 +1717,7 @@ public: valid = false; } else { Error errn; - DirAccessRef da = DirAccess::open(sdk_path.plus_file("tools"), &errn); + DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn); if (errn != OK) { err += TTR("Invalid Android SDK path for custom build in Editor Settings.") + "\n"; valid = false; diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 99080eeb3c..9ae47d6174 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -76,7 +76,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' - doNotStrip '**/*.so' + + // Should be uncommented for development purpose within Android Studio + // doNotStrip '**/*.so' } // Both signing and zip-aligning will be done at export time diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 6bb438c249..19eee5a315 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -26,7 +26,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' - doNotStrip '**/*.so' + + // Should be uncommented for development purpose within Android Studio + // doNotStrip '**/*.so' } sourceSets { diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 8b38113e09..a6730903cc 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -38,7 +38,7 @@ #include "api/jni_singleton.h" #include "audio_driver_jandroid.h" #include "core/engine.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/project_settings.h" #include "dir_access_jandroid.h" #include "display_server_android.h" @@ -311,15 +311,15 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j int hat = 0; if (p_hat_x != 0) { if (p_hat_x < 0) - hat |= InputFilter::HAT_MASK_LEFT; + hat |= Input::HAT_MASK_LEFT; else - hat |= InputFilter::HAT_MASK_RIGHT; + hat |= Input::HAT_MASK_RIGHT; } if (p_hat_y != 0) { if (p_hat_y < 0) - hat |= InputFilter::HAT_MASK_UP; + hat |= Input::HAT_MASK_UP; else - hat |= InputFilter::HAT_MASK_DOWN; + hat |= Input::HAT_MASK_DOWN; } jevent.hat = hat; @@ -329,7 +329,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) { if (os_android) { String name = jstring_to_string(p_name, env); - InputFilter::get_singleton()->joy_connection_changed(p_device, p_connected, name); + Input::get_singleton()->joy_connection_changed(p_device, p_connected, name); } } diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 760157595c..9ae18415ba 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -88,7 +88,7 @@ void OS_Android::initialize() { } void OS_Android::initialize_joypads() { - InputFilter::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping()); + Input::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping()); // This queries/updates the currently connected devices/joypads. godot_java->init_input_devices(); diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 925bb9ac5d..4817abbb7a 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -35,7 +35,7 @@ #include <DirectWindow.h> -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "haiku_gl_view.h" diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 64f5690dd1..d3ef9400d4 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -33,7 +33,7 @@ #include "audio_driver_media_kit.h" #include "context_gl_haiku.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "drivers/unix/os_unix.h" #include "haiku_application.h" #include "haiku_direct_window.h" diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 96cf041c37..eb94e1d69b 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -33,7 +33,7 @@ #ifndef OS_IPHONE_H #define OS_IPHONE_H -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" #include "game_center.h" diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 39faae2d17..36076a2af9 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -252,6 +252,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re String current_line = lines[i]; current_line = current_line.replace("$GODOT_BASENAME", p_name); + current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name")); current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include")); current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false"); str_export += current_line + "\n"; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 81fe4cf0cc..feb0f0651a 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -32,7 +32,7 @@ #define OS_JAVASCRIPT_H #include "audio_driver_javascript.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "drivers/unix/os_unix.h" #include "servers/audio_server.h" #include "servers/rendering/rasterizer.h" diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 5d8b4fba48..07fa06bc06 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -217,15 +217,17 @@ def configure(env): env.ParseConfig("pkg-config libpng16 --cflags --libs") if not env["builtin_bullet"]: - # We need at least version 2.89 + # We need at least version 2.90 + min_bullet_version = "2.90" + import subprocess bullet_version = subprocess.check_output(["pkg-config", "bullet", "--modversion"]).strip() - if str(bullet_version) < "2.89": + if str(bullet_version) < min_bullet_version: # Abort as system bullet was requested but too old print( "Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format( - bullet_version, "2.89" + bullet_version, min_bullet_version ) ) sys.exit(255) diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 78ddef5ff6..e38b0c13d0 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -208,7 +208,7 @@ void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) { last_mouse_pos.x = win_x; last_mouse_pos.y = win_y; last_mouse_pos_valid = true; - InputFilter::get_singleton()->set_mouse_position(last_mouse_pos); + Input::get_singleton()->set_mouse_position(last_mouse_pos); } } } @@ -392,7 +392,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { XWarpPointer(x11_display, None, main_window.x11_window, 0, 0, 0, 0, (int)center.x, (int)center.y); - InputFilter::get_singleton()->set_mouse_position(center); + Input::get_singleton()->set_mouse_position(center); } } else { do_mouse_warp = false; @@ -2077,7 +2077,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, k->set_shift(true); } - InputFilter::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->accumulate_input_event(k); } memfree(utf8string); return; @@ -2220,14 +2220,14 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, k->set_metakey(false); } - bool last_is_pressed = InputFilter::get_singleton()->is_key_pressed(k->get_keycode()); + bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_keycode()); if (k->is_pressed()) { if (last_is_pressed) { k->set_echo(true); } } - InputFilter::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->accumulate_input_event(k); } void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data, @@ -2486,12 +2486,12 @@ void DisplayServerX11::process_events() { // in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out xi.mouse_pos_to_filter = pos; } - InputFilter::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->accumulate_input_event(st); } else { if (!xi.state.has(index)) // Defensive break; xi.state.erase(index); - InputFilter::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->accumulate_input_event(st); } } break; @@ -2510,7 +2510,7 @@ void DisplayServerX11::process_events() { sd->set_index(index); sd->set_position(pos); sd->set_relative(pos - curr_pos_elem->value()); - InputFilter::get_singleton()->accumulate_input_event(sd); + Input::get_singleton()->accumulate_input_event(sd); curr_pos_elem->value() = pos; } @@ -2580,7 +2580,7 @@ void DisplayServerX11::process_events() { case FocusOut: window_has_focus = false; - InputFilter::get_singleton()->release_pressed_events(); + Input::get_singleton()->release_pressed_events(); _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT); window_focused = false; @@ -2609,7 +2609,7 @@ void DisplayServerX11::process_events() { st->set_index(E->key()); st->set_window_id(window_id); st->set_position(E->get()); - InputFilter::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->accumulate_input_event(st); } xi.state.clear(); #endif @@ -2671,7 +2671,7 @@ void DisplayServerX11::process_events() { } } - InputFilter::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->accumulate_input_event(mb); } break; case MotionNotify: { @@ -2773,8 +2773,8 @@ void DisplayServerX11::process_events() { mm->set_button_mask(mouse_get_button_state()); mm->set_position(posi); mm->set_global_position(posi); - InputFilter::get_singleton()->set_mouse_position(posi); - mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed()); + Input::get_singleton()->set_mouse_position(posi); + mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); mm->set_relative(rel); @@ -2785,7 +2785,7 @@ void DisplayServerX11::process_events() { // this is so that the relative motion doesn't get messed up // after we regain focus. if (window_has_focus || !mouse_mode_grab) - InputFilter::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->accumulate_input_event(mm); } break; case KeyPress: @@ -2978,7 +2978,7 @@ void DisplayServerX11::process_events() { */ } - InputFilter::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_accumulated_events(); } void DisplayServerX11::release_rendering_thread() { @@ -3373,7 +3373,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events); + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; @@ -3606,8 +3606,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } } #endif - - WindowID main_window = _create_window(p_mode, p_flags, Rect2i(Point2(), p_resolution)); + Point2i window_position( + (screen_get_size(0).width - p_resolution.width) / 2, + (screen_get_size(0).height - p_resolution.height) / 2); + WindowID main_window = _create_window(p_mode, p_flags, Rect2i(window_position, p_resolution)); for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 113e504e9b..8f090d3fad 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -35,7 +35,7 @@ #include "servers/display_server.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 381eb909ba..5ceea788e0 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -71,7 +71,7 @@ void JoypadLinux::Joypad::reset() { dpad = 0; fd = -1; - InputFilter::JoyAxis jx; + Input::JoyAxis jx; jx.min = -1; jx.value = 0.0f; for (int i = 0; i < MAX_ABS; i++) { @@ -80,7 +80,7 @@ void JoypadLinux::Joypad::reset() { } } -JoypadLinux::JoypadLinux(InputFilter *in) { +JoypadLinux::JoypadLinux(Input *in) { exit_udev = false; input = in; joy_thread = Thread::create(joy_thread_func, this); @@ -436,11 +436,11 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { joy.ff_effect_timestamp = p_timestamp; } -InputFilter::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const { +Input::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const { int min = p_abs->minimum; int max = p_abs->maximum; - InputFilter::JoyAxis jx; + Input::JoyAxis jx; if (min < 0) { jx.min = -1; @@ -492,11 +492,11 @@ void JoypadLinux::process_joypads() { case ABS_HAT0X: if (ev.value != 0) { if (ev.value < 0) - joy->dpad |= InputFilter::HAT_MASK_LEFT; + joy->dpad |= Input::HAT_MASK_LEFT; else - joy->dpad |= InputFilter::HAT_MASK_RIGHT; + joy->dpad |= Input::HAT_MASK_RIGHT; } else - joy->dpad &= ~(InputFilter::HAT_MASK_LEFT | InputFilter::HAT_MASK_RIGHT); + joy->dpad &= ~(Input::HAT_MASK_LEFT | Input::HAT_MASK_RIGHT); input->joy_hat(i, joy->dpad); break; @@ -504,11 +504,11 @@ void JoypadLinux::process_joypads() { case ABS_HAT0Y: if (ev.value != 0) { if (ev.value < 0) - joy->dpad |= InputFilter::HAT_MASK_UP; + joy->dpad |= Input::HAT_MASK_UP; else - joy->dpad |= InputFilter::HAT_MASK_DOWN; + joy->dpad |= Input::HAT_MASK_DOWN; } else - joy->dpad &= ~(InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_DOWN); + joy->dpad &= ~(Input::HAT_MASK_UP | Input::HAT_MASK_DOWN); input->joy_hat(i, joy->dpad); break; @@ -517,7 +517,7 @@ void JoypadLinux::process_joypads() { if (ev.code >= MAX_ABS) return; if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) { - InputFilter::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value); + Input::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value); joy->curr_axis[joy->abs_map[ev.code]] = value; } break; diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h index 1d2ed5bbc1..0d175193a5 100644 --- a/platform/linuxbsd/joypad_linux.h +++ b/platform/linuxbsd/joypad_linux.h @@ -33,7 +33,7 @@ #define JOYPAD_LINUX_H #ifdef JOYDEV_ENABLED -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/mutex.h" #include "core/os/thread.h" @@ -41,7 +41,7 @@ struct input_absinfo; class JoypadLinux { public: - JoypadLinux(InputFilter *in); + JoypadLinux(Input *in); ~JoypadLinux(); void process_joypads(); @@ -53,7 +53,7 @@ private: }; struct Joypad { - InputFilter::JoyAxis curr_axis[MAX_ABS]; + Input::JoyAxis curr_axis[MAX_ABS]; int key_map[MAX_KEY]; int abs_map[MAX_ABS]; int dpad; @@ -74,7 +74,7 @@ private: bool exit_udev; Mutex joy_mutex; Thread *joy_thread; - InputFilter *input; + Input *input; Joypad joypads[JOYPADS_MAX]; Vector<String> attached_devices; @@ -95,7 +95,7 @@ private: void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_stop(int p_id, uint64_t p_timestamp); - InputFilter::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const; + Input::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const; }; #endif diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 5b9a25bd8b..7b76f7394b 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -64,7 +64,7 @@ void OS_LinuxBSD::initialize() { void OS_LinuxBSD::initialize_joypads() { #ifdef JOYDEV_ENABLED - joypad = memnew(JoypadLinux(InputFilter::get_singleton())); + joypad = memnew(JoypadLinux(Input::get_singleton())); #endif } diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 100cb53ba3..391f29e8a3 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -31,7 +31,7 @@ #ifndef OS_LINUXBSD_H #define OS_LINUXBSD_H -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "crash_handler_linuxbsd.h" #include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsamidi/midi_driver_alsamidi.h" diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index 86ceb51763..8133dfe2c4 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -33,7 +33,7 @@ #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition. -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "servers/display_server.h" #if defined(OPENGL_ENABLED) diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 074fc3be0d..9d92992332 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -55,6 +55,10 @@ #include <QuartzCore/CAMetalLayer.h> #endif +#ifndef NSAppKitVersionNumber10_14 +#define NSAppKitVersionNumber10_14 1671 +#endif + #define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton())) static void _get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) { @@ -70,7 +74,7 @@ static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_loc p_wd.mouse_pos.x = p.x * p_backingScaleFactor; p_wd.mouse_pos.y = (contentRect.size.height - p.y) * p_backingScaleFactor; DS_OSX->last_mouse_pos = p_wd.mouse_pos; - InputFilter::get_singleton()->set_mouse_position(p_wd.mouse_pos); + Input::get_singleton()->set_mouse_position(p_wd.mouse_pos); return p_wd.mouse_pos; } @@ -120,7 +124,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { k->set_physical_keycode(KEY_PERIOD); k->set_echo([event isARepeat]); - InputFilter::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->accumulate_input_event(k); } } @@ -429,7 +433,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [wd.window_view backingScaleFactor] : 1.0; _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream], backingScaleFactor); - InputFilter::get_singleton()->set_mouse_position(wd.mouse_pos); + Input::get_singleton()->set_mouse_position(wd.mouse_pos); DS_OSX->window_focused = true; DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); @@ -755,7 +759,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i mb->set_doubleclick([event clickCount] == 2); } - InputFilter::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->accumulate_input_event(mb); } - (void)mouseDown:(NSEvent *)event { @@ -804,15 +808,15 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i mm->set_tilt(Vector2(p.x, p.y)); } mm->set_global_position(pos); - mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed()); + mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); Vector2i relativeMotion = Vector2i(); relativeMotion.x = [event deltaX] * backingScaleFactor; relativeMotion.y = [event deltaY] * backingScaleFactor; mm->set_relative(relativeMotion); _get_key_modifier_state([event modifierFlags], mm); - InputFilter::get_singleton()->set_mouse_position(wd.mouse_pos); - InputFilter::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->set_mouse_position(wd.mouse_pos); + Input::get_singleton()->accumulate_input_event(mm); } - (void)rightMouseDown:(NSEvent *)event { @@ -887,7 +891,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i ev->set_position(_get_mouse_pos(wd, [event locationInWindow], backingScaleFactor)); ev->set_factor([event magnification] + 1.0); - InputFilter::get_singleton()->accumulate_input_event(ev); + Input::get_singleton()->accumulate_input_event(ev); } - (void)viewDidChangeBackingProperties { @@ -1353,7 +1357,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, int button, doubl DS_OSX->last_button_state |= mask; sc->set_button_mask(DS_OSX->last_button_state); - InputFilter::get_singleton()->accumulate_input_event(sc); + Input::get_singleton()->accumulate_input_event(sc); sc.instance(); sc->set_window_id(window_id); @@ -1365,7 +1369,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, int button, doubl DS_OSX->last_button_state &= ~mask; sc->set_button_mask(DS_OSX->last_button_state); - InputFilter::get_singleton()->accumulate_input_event(sc); + Input::get_singleton()->accumulate_input_event(sc); } inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy, int modifierFlags) { @@ -1380,7 +1384,7 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy pg->set_position(wd.mouse_pos); pg->set_delta(Vector2(-dx, -dy)); - InputFilter::get_singleton()->accumulate_input_event(pg); + Input::get_singleton()->accumulate_input_event(pg); } - (void)scrollWheel:(NSEvent *)event { @@ -3002,13 +3006,13 @@ DisplayServerOSX::LatinKeyboardVariant DisplayServerOSX::get_latin_keyboard_vari void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; - InputFilter::get_singleton()->accumulate_input_event(ev); + Input::get_singleton()->accumulate_input_event(ev); } void DisplayServerOSX::_release_pressed_events() { _THREAD_SAFE_METHOD_ - if (InputFilter::get_singleton()) { - InputFilter::get_singleton()->release_pressed_events(); + if (Input::get_singleton()) { + Input::get_singleton()->release_pressed_events(); } } @@ -3084,7 +3088,7 @@ void DisplayServerOSX::process_events() { if (!drop_events) { _process_key_events(); - InputFilter::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_accumulated_events(); } [autoreleasePool drain]; @@ -3393,7 +3397,7 @@ bool DisplayServerOSX::is_console_visible() const { } DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events); + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; drop_events = false; @@ -3524,7 +3528,10 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode } #endif - WindowID main_window = _create_window(p_mode, Rect2i(Point2i(), p_resolution)); + Point2i window_position( + (screen_get_size(0).width - p_resolution.width) / 2, + (screen_get_size(0).height - p_resolution.height) / 2); + WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution)); for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index 643acd8944..7f5ec05967 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -395,38 +395,38 @@ bool joypad::check_ff_features() { static int process_hat_value(int p_min, int p_max, int p_value) { int range = (p_max - p_min + 1); int value = p_value - p_min; - int hat_value = InputFilter::HAT_MASK_CENTER; + int hat_value = Input::HAT_MASK_CENTER; if (range == 4) { value *= 2; } switch (value) { case 0: - hat_value = InputFilter::HAT_MASK_UP; + hat_value = Input::HAT_MASK_UP; break; case 1: - hat_value = InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_RIGHT; break; case 2: - hat_value = InputFilter::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_RIGHT; break; case 3: - hat_value = InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_RIGHT; + hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_RIGHT; break; case 4: - hat_value = InputFilter::HAT_MASK_DOWN; + hat_value = Input::HAT_MASK_DOWN; break; case 5: - hat_value = InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_LEFT; break; case 6: - hat_value = InputFilter::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_LEFT; break; case 7: - hat_value = InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_LEFT; + hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_LEFT; break; default: - hat_value = InputFilter::HAT_MASK_CENTER; + hat_value = Input::HAT_MASK_CENTER; break; } return hat_value; @@ -438,8 +438,8 @@ void JoypadOSX::poll_joypads() const { } } -static const InputFilter::JoyAxis axis_correct(int p_value, int p_min, int p_max) { - InputFilter::JoyAxis jx; +static const Input::JoyAxis axis_correct(int p_value, int p_min, int p_max) { + Input::JoyAxis jx; if (p_min < 0) { jx.min = -1; if (p_value < 0) { @@ -571,7 +571,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { } } -JoypadOSX::JoypadOSX(InputFilter *in) { +JoypadOSX::JoypadOSX(Input *in) { self = this; input = in; diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index 62027c6a30..fc176b0990 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -40,7 +40,7 @@ #include <ForceFeedback/ForceFeedbackConstants.h> #include <IOKit/hid/IOHIDLib.h> -#include "core/input/input_filter.h" +#include "core/input/input.h" struct rec_element { IOHIDElementRef ref; @@ -94,7 +94,7 @@ class JoypadOSX { }; private: - InputFilter *input; + Input *input; IOHIDManagerRef hid_manager; Vector<joypad> device_list; @@ -118,7 +118,7 @@ public: void _device_added(IOReturn p_res, IOHIDDeviceRef p_device); void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device); - JoypadOSX(InputFilter *in); + JoypadOSX(Input *in); ~JoypadOSX(); }; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index d2c67cff9f..9204a145bf 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -31,7 +31,7 @@ #ifndef OS_OSX_H #define OS_OSX_H -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "crash_handler_osx.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/coremidi/midi_driver_coremidi.h" diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 49cb056c9f..f132ed9514 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -60,39 +60,31 @@ public: switch (p_type) { case ERR_WARNING: - if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { - os_log_info(OS_LOG_DEFAULT, - "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - } + os_log_info(OS_LOG_DEFAULT, + "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details); logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_SCRIPT: - if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { - os_log_error(OS_LOG_DEFAULT, - "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - } + os_log_error(OS_LOG_DEFAULT, + "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details); logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_SHADER: - if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { - os_log_error(OS_LOG_DEFAULT, - "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - } + os_log_error(OS_LOG_DEFAULT, + "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details); logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_ERROR: default: - if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { - os_log_error(OS_LOG_DEFAULT, - "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", - err_details, p_function, p_file, p_line); - } + os_log_error(OS_LOG_DEFAULT, + "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details); logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; @@ -136,7 +128,7 @@ void OS_OSX::initialize_core() { } void OS_OSX::initialize_joypads() { - joypad_osx = memnew(JoypadOSX(InputFilter::get_singleton())); + joypad_osx = memnew(JoypadOSX(Input::get_singleton())); } void OS_OSX::initialize() { diff --git a/platform/server/os_server.h b/platform/server/os_server.h index 62028b26e4..b273e8d4e4 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -31,7 +31,7 @@ #ifndef OS_SERVER_H #define OS_SERVER_H -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "drivers/dummy/texture_loader_dummy.h" #include "drivers/unix/os_unix.h" #ifdef __APPLE__ diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index 054b67ddc8..69431052e5 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -31,7 +31,7 @@ #ifndef JOYPAD_UWP_H #define JOYPAD_UWP_H -#include "core/input/input_filter.h" +#include "core/input/input.h" ref class JoypadUWP sealed { diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index ad0efa1d03..2233f6a413 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -32,7 +32,7 @@ #define OS_UWP_H #include "context_egl_uwp.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/transform_2d.h" #include "core/os/os.h" #include "core/ustring.h" diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index 1d9eba22d8..996d9722f5 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -38,11 +38,13 @@ // Backtrace code code based on: https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app -#include <psapi.h> #include <algorithm> #include <iterator> +#include <string> #include <vector> +#include <psapi.h> + #pragma comment(lib, "psapi.lib") #pragma comment(lib, "dbghelp.lib") diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index ebe9a7d27a..e4fe7f04d0 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -666,7 +666,7 @@ void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) { old_x = mouse_pos.x; old_y = mouse_pos.y; old_invalid = false; - InputFilter::get_singleton()->set_mouse_position(Point2i(mouse_pos.x, mouse_pos.y)); + Input::get_singleton()->set_mouse_position(Point2i(mouse_pos.x, mouse_pos.y)); } } } @@ -1511,7 +1511,7 @@ void DisplayServerWindows::process_events() { if (!drop_events) { _process_key_events(); - InputFilter::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_accumulated_events(); } } @@ -1715,7 +1715,7 @@ void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float event->set_pressed(p_pressed); event->set_position(Vector2(p_x, p_y)); - InputFilter::get_singleton()->accumulate_input_event(event); + Input::get_singleton()->accumulate_input_event(event); } void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, int idx) { @@ -1735,7 +1735,7 @@ void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, event->set_position(Vector2(p_x, p_y)); event->set_relative(Vector2(p_x, p_y) - curr->get()); - InputFilter::get_singleton()->accumulate_input_event(event); + Input::get_singleton()->accumulate_input_event(event); curr->get() = Vector2(p_x, p_y); } @@ -1843,7 +1843,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA control_mem = false; shift_mem = false; } else { // WM_INACTIVE - InputFilter::get_singleton()->release_pressed_events(); + Input::get_singleton()->release_pressed_events(); _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT); windows[window_id].window_focused = false; alt_mem = false; @@ -1940,7 +1940,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_position(c); mm->set_global_position(c); - InputFilter::get_singleton()->set_mouse_position(c); + Input::get_singleton()->set_mouse_position(c); mm->set_speed(Vector2(0, 0)); if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) { @@ -1973,7 +1973,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (windows[window_id].window_has_focus && mm->get_relative() != Vector2()) - InputFilter::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->accumulate_input_event(mm); } delete[] lpb; } break; @@ -2001,7 +2001,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) { + if (Input::get_singleton()->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translation LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { @@ -2074,8 +2074,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA SetCursorPos(pos.x, pos.y); } - InputFilter::get_singleton()->set_mouse_position(mm->get_position()); - mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed()); + Input::get_singleton()->set_mouse_position(mm->get_position()); + mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); if (old_invalid) { @@ -2088,7 +2088,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; if (windows[window_id].window_has_focus) { - InputFilter::get_singleton()->parse_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event @@ -2098,7 +2098,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) { + if (Input::get_singleton()->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translation LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { @@ -2161,8 +2161,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA SetCursorPos(pos.x, pos.y); } - InputFilter::get_singleton()->set_mouse_position(mm->get_position()); - mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed()); + Input::get_singleton()->set_mouse_position(mm->get_position()); + mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); if (old_invalid) { @@ -2175,12 +2175,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; if (windows[window_id].window_has_focus) - InputFilter::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->accumulate_input_event(mm); } break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: - if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) { + if (Input::get_singleton()->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translations for left button LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { @@ -2347,7 +2347,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_global_position(mb->get_position()); - InputFilter::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->accumulate_input_event(mb); if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) { //send release for mouse wheel Ref<InputEventMouseButton> mbd = mb->duplicate(); @@ -2355,7 +2355,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA last_button_state &= ~(1 << (mbd->get_button_index() - 1)); mbd->set_button_mask(last_button_state); mbd->set_pressed(false); - InputFilter::get_singleton()->accumulate_input_event(mbd); + Input::get_singleton()->accumulate_input_event(mbd); } } break; @@ -2444,7 +2444,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_ENTERSIZEMOVE: { - InputFilter::get_singleton()->release_pressed_events(); + Input::get_singleton()->release_pressed_events(); move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); } break; case WM_EXITSIZEMOVE: { @@ -2652,7 +2652,7 @@ void DisplayServerWindows::_process_key_events() { if (k->get_unicode() < 32) k->set_unicode(0); - InputFilter::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->accumulate_input_event(k); } //do nothing @@ -2693,7 +2693,7 @@ void DisplayServerWindows::_process_key_events() { k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)))); - InputFilter::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->accumulate_input_event(k); } break; } @@ -2897,7 +2897,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } #endif - WindowID main_window = _create_window(p_mode, 0, Rect2i(Point2i(), p_resolution)); + Point2i window_position( + (screen_get_size(0).width - p_resolution.width) / 2, + (screen_get_size(0).height - p_resolution.height) / 2); + WindowID main_window = _create_window(p_mode, 0, Rect2i(window_position, p_resolution)); for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); @@ -2945,7 +2948,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win r_error = OK; ((OS_Windows *)OS::get_singleton())->set_main_window(windows[MAIN_WINDOW_ID].hWnd); - InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events); + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); } Vector<String> DisplayServerWindows::get_rendering_drivers_func() { diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 5cd240ffb0..6243f54cfa 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -33,7 +33,7 @@ #include "servers/display_server.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "crash_handler_windows.h" diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 437c3b733d..2adf2a8652 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -54,7 +54,7 @@ JoypadWindows::JoypadWindows() { JoypadWindows::JoypadWindows(HWND *hwnd) { - input = InputFilter::get_singleton(); + input = Input::get_singleton(); hWnd = hwnd; joypad_count = 0; dinput = nullptr; @@ -436,46 +436,46 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { // BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);" // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks if (LOWORD(p_dpad) == 0xFFFF) { - dpad_val = InputFilter::HAT_MASK_CENTER; + dpad_val = Input::HAT_MASK_CENTER; } if (p_dpad == 0) { - dpad_val = InputFilter::HAT_MASK_UP; + dpad_val = Input::HAT_MASK_UP; } else if (p_dpad == 4500) { - dpad_val = (InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_RIGHT); + dpad_val = (Input::HAT_MASK_UP | Input::HAT_MASK_RIGHT); } else if (p_dpad == 9000) { - dpad_val = InputFilter::HAT_MASK_RIGHT; + dpad_val = Input::HAT_MASK_RIGHT; } else if (p_dpad == 13500) { - dpad_val = (InputFilter::HAT_MASK_RIGHT | InputFilter::HAT_MASK_DOWN); + dpad_val = (Input::HAT_MASK_RIGHT | Input::HAT_MASK_DOWN); } else if (p_dpad == 18000) { - dpad_val = InputFilter::HAT_MASK_DOWN; + dpad_val = Input::HAT_MASK_DOWN; } else if (p_dpad == 22500) { - dpad_val = (InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_LEFT); + dpad_val = (Input::HAT_MASK_DOWN | Input::HAT_MASK_LEFT); } else if (p_dpad == 27000) { - dpad_val = InputFilter::HAT_MASK_LEFT; + dpad_val = Input::HAT_MASK_LEFT; } else if (p_dpad == 31500) { - dpad_val = (InputFilter::HAT_MASK_LEFT | InputFilter::HAT_MASK_UP); + dpad_val = (Input::HAT_MASK_LEFT | Input::HAT_MASK_UP); } input->joy_hat(p_device, dpad_val); }; -InputFilter::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { +Input::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { - InputFilter::JoyAxis jx; + Input::JoyAxis jx; if (Math::abs(p_val) < MIN_JOY_AXIS) { jx.min = p_trigger ? 0 : -1; jx.value = 0.0f; diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index 0db789c335..fefdcf1673 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -117,7 +117,7 @@ private: HWND *hWnd; HANDLE xinput_dll; LPDIRECTINPUT8 dinput; - InputFilter *input; + Input *input; int id_to_change; int joypad_count; @@ -141,7 +141,7 @@ private: void joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp); void joypad_vibration_stop_xinput(int p_device, uint64_t p_timestamp); - InputFilter::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; + Input::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const; XInputGetState_t xinput_get_state; XInputSetState_t xinput_set_state; }; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 6bdfc75ebb..7226109e57 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -31,7 +31,7 @@ #ifndef OS_WINDOWS_H #define OS_WINDOWS_H -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "crash_handler_windows.h" diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c46b6eeb5c..8ba334bc67 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const { return monitorable; } -Array Area2D::get_overlapping_bodies() const { +TypedArray<Node2D> Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Node2D> ret; ret.resize(body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { @@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const { return ret; } -Array Area2D::get_overlapping_areas() const { +TypedArray<Area2D> Area2D::get_overlapping_areas() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Area2D> ret; ret.resize(area_map.size()); int idx = 0; for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index c5e6635412..0e2c0ac672 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -178,8 +178,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; //function for script - Array get_overlapping_areas() const; //function for script + TypedArray<Node2D> get_overlapping_bodies() const; //function for script + TypedArray<Area2D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index c45eab70df..43c54ffd17 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -43,7 +43,7 @@ Line2D::Line2D() { _begin_cap_mode = LINE_CAP_NONE; _end_cap_mode = LINE_CAP_NONE; _width = 10; - _default_color = Color(0.4, 0.5, 1); + _default_color = Color(1, 1, 1); _texture_mode = LINE_TEXTURE_NONE; _sharp_limit = 2.f; _round_precision = 8; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index d77fd5b097..19484442b1 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const { return vertices; } -void NavigationPolygon::_set_polygons(const Array &p_array) { +void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { { MutexLock lock(navmesh_generation); @@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const Array &p_array) { +void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) { outlines.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 73e056a353..cbfe4299fb 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -55,10 +55,10 @@ class NavigationPolygon : public Resource { protected: static void _bind_methods(); - void _set_polygons(const Array &p_array); + void _set_polygons(const TypedArray<Vector<int32_t>> &p_array); Array _get_polygons() const; - void _set_outlines(const Array &p_array); + void _set_outlines(const TypedArray<Vector<int32_t>> &p_array); Array _get_outlines() const; public: diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index ed8481db4a..149d5c6b0d 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -102,7 +102,7 @@ void Path2D::_notification(int p_what) { #else const float line_width = 2; #endif - const Color color = Color(1.0, 1.0, 1.0, 1.0); + const Color color = Color(0.5, 0.6, 1.0, 0.7); for (int i = 0; i < curve->get_point_count(); i++) { @@ -162,7 +162,6 @@ void Path2D::_bind_methods() { Path2D::Path2D() { set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default - set_self_modulate(Color(0.5, 0.6, 1.0, 0.7)); } ///////////////////////////////////////////////////////////////////////////////// diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 21dc9537ec..de15f0efc2 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : set_pickable(false); } -Array PhysicsBody2D::get_collision_exceptions() { +TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons return ccd_mode; } -Array RigidBody2D::get_colliding_bodies() const { +TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); - Array ret; + TypedArray<Node2D> ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 0d92a820e3..75f4f778bf 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -67,7 +67,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -256,7 +256,7 @@ public: void add_force(const Vector2 &p_offset, const Vector2 &p_force); void add_torque(float p_torque); - Array get_colliding_bodies() const; //function for script + TypedArray<Node2D> get_colliding_bodies() const; //function for script virtual String get_configuration_warning() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1cf12e4421..9628c01718 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1691,27 +1691,27 @@ bool TileMap::is_centered_textures_enabled() const { return centered_textures; } -Array TileMap::get_used_cells() const { +TypedArray<Vector2i> TileMap::get_used_cells() const { - Array a; + TypedArray<Vector2i> a; a.resize(tile_map.size()); int i = 0; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a[i++] = p; } return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { +TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const { - Array a; + TypedArray<Vector2i> a; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { if (E->value().id == p_id) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index d9490aae13..cc1537f583 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -328,8 +328,8 @@ public: void set_centered_textures(bool p_enable); bool is_centered_textures_enabled() const; - Array get_used_cells() const; - Array get_used_cells_by_id(int p_id) const; + TypedArray<Vector2i> get_used_cells() const; + TypedArray<Vector2i> get_used_cells_by_id(int p_id) const; Rect2 get_used_rect(); // Not const because of cache void set_occluder_light_mask(int p_mask); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 2cb979a0e0..85fd05ac15 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -30,7 +30,7 @@ #include "touch_screen_button.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/input/input_map.h" #include "core/os/os.h" #include "scene/main/window.h" @@ -290,7 +290,7 @@ void TouchScreenButton::_press(int p_finger_pressed) { if (action != StringName()) { - InputFilter::get_singleton()->action_press(action); + Input::get_singleton()->action_press(action); Ref<InputEventAction> iea; iea.instance(); iea->set_action(action); @@ -308,7 +308,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) { if (action != StringName()) { - InputFilter::get_singleton()->action_release(action); + Input::get_singleton()->action_release(action); if (!p_exiting_tree) { Ref<InputEventAction> iea; diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e..b72483d71b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray<Node3D> Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray<Area3D> Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b08..f6503c6d2d 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray<Node3D> get_overlapping_bodies() const; + TypedArray<Area3D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 9928246d2b..c048f60ebd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -301,6 +301,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); + BIND_ENUM_CONSTANT(PARAM_SIZE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index d56a095a5b..cdc8db8aea 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -307,19 +307,22 @@ Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const { Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { - if (get_material_override() != Ref<Material>()) { - return get_material_override(); - } else if (p_surface < materials.size()) { - return materials[p_surface]; - } else { - Ref<Mesh> mesh = get_mesh(); + Ref<Material> material_override = get_material_override(); + if (material_override.is_valid()) { + return material_override; + } - if (mesh.is_null() || p_surface >= mesh->get_surface_count()) { - return Ref<Material>(); - } + Ref<Material> surface_material = get_surface_material(p_surface); + if (surface_material.is_valid()) { + return surface_material; + } + Ref<Mesh> mesh = get_mesh(); + if (mesh.is_valid()) { return mesh->surface_get_material(p_surface); } + + return Ref<Material>(); } void MeshInstance3D::_mesh_changed() { diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 72d1762ab5..3991efc7c0 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 2e71020233..0e719f5108 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody3D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e23005..973822653a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) { set_physics_process_internal(false); Vector<int> sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658..0bccd3f8fc 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 203c3cd812..f30c58be55 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - const Vector2 *uvr; + const Vector2 *uvr = nullptr; Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - const Vector3 *nr; + const Vector3 *nr = nullptr; Vector<int> index = a[Mesh::ARRAY_INDEX]; - bool read_uv = false; - bool read_normals = false; - if (uv.size()) { - uvr = uv.ptr(); - read_uv = true; } if (normals.size()) { - read_normals = true; nr = normals.ptr(); } @@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[ir[j * 3 + k]]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[ir[j * 3 + k]]; } @@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[j * 3 + k]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[j * 3 + k]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[j * 3 + k]; } diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 0373114e7d..6f41629bac 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "xr_nodes.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "servers/xr/xr_interface.h" #include "servers/xr_server.h" @@ -206,7 +206,7 @@ void XRController3D::_notification(int p_what) { // check button states for (int i = 0; i < 16; i++) { bool was_pressed = (button_states & mask) == mask; - bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i); + bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i); if (!was_pressed && is_pressed) { emit_signal("button_pressed", i); @@ -306,7 +306,7 @@ bool XRController3D::is_button_pressed(int p_button) const { return false; }; - return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button); + return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button); }; float XRController3D::get_joystick_axis(int p_axis) const { @@ -315,7 +315,7 @@ float XRController3D::get_joystick_axis(int p_axis) const { return 0.0; }; - return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis); + return Input::get_singleton()->get_joy_axis(joy_id, p_axis); }; real_t XRController3D::get_rumble() const { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index b657833a3b..946f759610 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -950,13 +950,13 @@ void AnimationPlayer::_animation_process(float p_delta) { play(queued.front()->get()); String new_name = playback.assigned; queued.pop_front(); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } else { //stop(); playing = false; _set_process(false); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); } end_reached = false; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 5e0f4c91e8..63878a0b26 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -30,7 +30,7 @@ #include "color_picker.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 0fe65462e4..3af730de23 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -30,7 +30,7 @@ #include "graph_edit.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "scene/gui/box_container.h" @@ -804,7 +804,7 @@ void GraphEdit::set_selected(Node *p_child) { void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; - if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)))) { + if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } @@ -823,7 +823,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { // Snapping can be toggled temporarily by holding down Ctrl. // This is done here as to not toggle the grid when holding down Ctrl. - if (is_using_snap() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { const int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } @@ -886,7 +886,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) { - if (!just_selected && drag_accum == Vector2() && InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); @@ -948,7 +948,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { drag_accum = Vector2(); drag_origin = get_local_mouse_position(); just_selected = !gn->is_selected(); - if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) { @@ -976,7 +976,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } else { if (_filter_input(b->get_position())) return; - if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) + if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; @@ -1035,16 +1035,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } - if (b->get_button_index() == BUTTON_WHEEL_UP && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_DOWN && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) { + if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) { + if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); } - if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) { + if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 1e933c9aa1..a247863298 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -30,7 +30,7 @@ #include "popup_menu.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/print_string.h" @@ -594,7 +594,7 @@ void PopupMenu::_notification(int p_what) { } break; case NOTIFICATION_POST_POPUP: { - initial_button_mask = InputFilter::get_singleton()->get_mouse_button_mask(); + initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); during_grabbed_click = (bool)initial_button_mask; } break; case NOTIFICATION_WM_SIZE_CHANGED: { diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 8572d570fb..94628f7cea 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -30,7 +30,7 @@ #include "spin_box.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/expression.h" Size2 SpinBox::get_minimum_size() const { @@ -77,7 +77,7 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) { void SpinBox::_range_click_timeout() { - if (!drag.enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { bool up = get_local_mouse_position().y < (get_size().height / 2); set_value(get_value() + (up ? get_step() : -get_step())); @@ -149,7 +149,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { if (drag.enabled) { drag.enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(drag.capture_pos); } drag.allowed = false; @@ -166,7 +166,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) { set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max())); } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); drag.enabled = true; drag.base_val = get_value(); drag.diff_y = 0; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 36e35897d1..2d63d86048 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -30,7 +30,7 @@ #include "text_edit.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -446,7 +446,7 @@ void TextEdit::_click_selection_held() { // Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD // and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem. // I'm unsure if there's an actual fix that doesn't have a ton of side effects. - if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { switch (selection.selecting_mode) { case Selection::MODE_POINTER: { _update_selection_mode_pointer(); @@ -1064,11 +1064,6 @@ void TextEdit::_notification(int p_what) { break; } - // re-adjust if we went backwards. - if (color != previous_color && !is_whitespace) { - characters++; - } - if (str[j] == '\t') { tabs += minimap_tab_size; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 509a52d36a..aad36ebf02 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -30,7 +30,7 @@ #include "tree.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/math/math_funcs.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -1425,7 +1425,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].custom_button) { if (cache.hover_item == p_item && cache.hover_cell == i) { - if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { draw_style_box(cache.custom_button_pressed, ir); } else { draw_style_box(cache.custom_button_hover, ir); @@ -1661,7 +1661,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { void Tree::_range_click_timeout() { - if (range_item_last && !range_drag_enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { Point2 pos = get_local_mouse_position() - cache.bg->get_offset(); if (show_column_titles) { @@ -2048,9 +2048,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool void Tree::_text_editor_modal_close() { - if (InputFilter::get_singleton()->is_key_pressed(KEY_ESCAPE) || - InputFilter::get_singleton()->is_key_pressed(KEY_KP_ENTER) || - InputFilter::get_singleton()->is_key_pressed(KEY_ENTER)) { + if (Input::get_singleton()->is_key_pressed(KEY_ESCAPE) || + Input::get_singleton()->is_key_pressed(KEY_KP_ENTER) || + Input::get_singleton()->is_key_pressed(KEY_ENTER)) { return; } @@ -2532,7 +2532,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { range_drag_enabled = true; range_drag_capture_pos = cpos; range_drag_base = popup_edited_item->get_range(popup_edited_item_col); - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); } } else { @@ -2594,7 +2594,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { if (range_drag_enabled) { range_drag_enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(range_drag_capture_pos); } else { Rect2 rect = get_selected()->get_meta("__focus_rect"); @@ -3238,7 +3238,7 @@ void Tree::clear() { if (pressing_for_editor) { if (range_drag_enabled) { range_drag_enabled = false; - InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(range_drag_capture_pos); } pressing_for_editor = false; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 2eacad68c3..b5d54b2199 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -30,7 +30,7 @@ #include "canvas_item.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/message_queue.h" #include "core/method_bind_ext.gen.inc" #include "scene/main/canvas_layer.h" diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 50f3bf834f..4c02a15531 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2693,9 +2693,9 @@ void Node::queue_delete() { } } -Array Node::_get_children() const { +TypedArray<Node> Node::_get_children() const { - Array arr; + TypedArray<Node> arr; int cc = get_child_count(); arr.resize(cc); for (int i = 0; i < cc; i++) diff --git a/scene/main/node.h b/scene/main/node.h index 5de07d506e..1c1b7bbd7a 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -37,6 +37,7 @@ #include "core/object.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "core/typed_array.h" #include "scene/main/scene_tree.h" class Viewport; @@ -182,7 +183,7 @@ private: void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const; Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const; - Array _get_children() const; + TypedArray<Node> _get_children() const; Array _get_groups() const; Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 0418b20e9c..22cd1c98ab 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -31,7 +31,7 @@ #include "scene_tree.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" #include "core/message_queue.h" @@ -576,7 +576,7 @@ void SceneTree::_main_window_go_back() { } void SceneTree::_main_window_focus_in() { - InputFilter *id = InputFilter::get_singleton(); + Input *id = Input::get_singleton(); if (id) { id->ensure_touch_mouse_raised(); } @@ -1422,7 +1422,7 @@ SceneTree::SceneTree() { current_scene = nullptr; int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x")); root->set_msaa(Viewport::MSAA(msaa_mode)); int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 72b1a877c1..b0718eed79 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/project_settings.h" #include "scene/2d/collision_object_2d.h" @@ -582,7 +582,7 @@ void Viewport::_notification(int p_what) { RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); } - if (physics_object_picking && (to_screen_rect == Rect2i() || InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED)) { + if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { #ifndef _3D_DISABLED Vector2 last_pos(1e20, 1e20); @@ -1517,7 +1517,7 @@ Vector2 Viewport::get_mouse_position() const { void Viewport::warp_mouse(const Vector2 &p_pos) { Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos); - InputFilter::get_singleton()->warp_mouse_position(gpos); + Input::get_singleton()->warp_mouse_position(gpos); } void Viewport::_gui_sort_roots() { @@ -2091,7 +2091,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.mouse_over = over; - DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)InputFilter::get_singleton()->get_default_cursor_shape(); + DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape(); if (over) { @@ -2411,7 +2411,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (from && p_event->is_pressed()) { Control *next = nullptr; - InputFilter *input = InputFilter::get_singleton(); + Input *input = Input::get_singleton(); if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) { @@ -3064,7 +3064,7 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor if (physics_object_picking && !is_input_handled()) { - if (InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED && + if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED && (Object::cast_to<InputEventMouseButton>(*ev) || Object::cast_to<InputEventMouseMotion>(*ev) || Object::cast_to<InputEventScreenDrag>(*ev) || @@ -3495,6 +3495,17 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); + BIND_ENUM_CONSTANT(MSAA_DISABLED); + BIND_ENUM_CONSTANT(MSAA_2X); + BIND_ENUM_CONSTANT(MSAA_4X); + BIND_ENUM_CONSTANT(MSAA_8X); + BIND_ENUM_CONSTANT(MSAA_16X); + BIND_ENUM_CONSTANT(MSAA_MAX); + + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX); + BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); @@ -3505,9 +3516,10 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED); BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED); + BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW); BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME); - + BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION); @@ -3519,18 +3531,12 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS); BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS); - BIND_ENUM_CONSTANT(MSAA_DISABLED); - BIND_ENUM_CONSTANT(MSAA_2X); - BIND_ENUM_CONSTANT(MSAA_4X); - BIND_ENUM_CONSTANT(MSAA_8X); - BIND_ENUM_CONSTANT(MSAA_16X); - BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); - BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); @@ -3746,15 +3752,15 @@ void SubViewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); + BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); + BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); + BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); + BIND_ENUM_CONSTANT(UPDATE_DISABLED); BIND_ENUM_CONSTANT(UPDATE_ONCE); BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_ALWAYS); - - BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); - BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); - BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); } SubViewport::SubViewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 0cbc957307..7e2df9fe42 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -116,7 +116,6 @@ public: }; enum RenderInfo { - RENDER_INFO_OBJECTS_IN_FRAME, RENDER_INFO_VERTICES_IN_FRAME, RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 264295325f..dc3ef5b508 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -757,8 +757,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); // Renamed in 4.0. + // Keep alphabetical ordering to easily locate classes and avoid duplicates. ClassDB::add_compatibility_class("AnimatedSprite", "AnimatedSprite2D"); ClassDB::add_compatibility_class("Area", "Area3D"); + ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D"); + ClassDB::add_compatibility_class("ARVRController", "XRController3D"); + ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D"); + ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); + ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D"); + ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); + ClassDB::add_compatibility_class("ARVRServer", "XRServer"); ClassDB::add_compatibility_class("BoneAttachment", "BoneAttachment3D"); ClassDB::add_compatibility_class("BoxShape", "BoxShape3D"); ClassDB::add_compatibility_class("BulletPhysicsDirectBodyState", "BulletPhysicsDirectBodyState3D"); @@ -806,6 +814,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D"); ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D"); ClassDB::add_compatibility_class("OmniLight", "OmniLight3D"); + ClassDB::add_compatibility_class("PanoramaSky", "Sky"); ClassDB::add_compatibility_class("Particles", "GPUParticles3D"); ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D"); ClassDB::add_compatibility_class("Path", "Path3D"); @@ -827,6 +836,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D"); ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D"); + ClassDB::add_compatibility_class("ProceduralSky", "Sky"); ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D"); ClassDB::add_compatibility_class("RayCast", "RayCast3D"); ClassDB::add_compatibility_class("RayShape", "RayShape3D"); @@ -857,12 +867,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("ProceduralSky", "Sky"); - ClassDB::add_compatibility_class("PanoramaSky", "Sky"); - ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D"); - ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D"); - ClassDB::add_compatibility_class("ARVRController", "XRController3D"); - ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D"); #endif diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index a613b01376..eea4d12d0e 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -1064,7 +1064,7 @@ void DynamicFont::update_oversampling() { ///////////////////////// -RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 9e628fc35a..ef4b9dd9d0 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -302,7 +302,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType); class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 835fef81e1..02ea5b24b8 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1004,8 +1004,8 @@ void Environment::_bind_methods() { ADD_GROUP("SSAO", "ssao_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.01"), "set_ssao_radius", "get_ssao_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.01"), "set_ssao_intensity", "get_ssao_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect"); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 192eefbf6a..267816f267 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -646,7 +646,7 @@ BitmapFont::~BitmapFont() { //////////// -RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/font.h b/scene/resources/font.h index ce75f27e2a..c233344529 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -200,7 +200,7 @@ public: class ResourceFormatLoaderBMFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6bb5be15f3..401b689145 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1359,7 +1359,7 @@ void ArrayMesh::regen_normalmaps() { } //dirty hack -bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = nullptr; +bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache); struct ArrayMeshLightmapSurface { @@ -1370,6 +1370,13 @@ struct ArrayMeshLightmapSurface { }; Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { + int *cache_data = nullptr; + unsigned int cache_size = 0; + bool use_cache = false; // Don't use cache + return lightmap_unwrap_cached(cache_data, cache_size, use_cache, p_base_transform, p_texel_size); +} + +Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform, float p_texel_size) { ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes."); @@ -1377,11 +1384,18 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe Vector<float> vertices; Vector<float> normals; Vector<int> indices; - Vector<int> face_materials; Vector<float> uv; - Vector<Pair<int, int>> uv_index; + Vector<Pair<int, int>> uv_indices; + + Vector<ArrayMeshLightmapSurface> lightmap_surfaces; + + // Keep only the scale + Transform transform = p_base_transform; + transform.origin = Vector3(); + transform.looking_at(Vector3(1, 0, 0), Vector3(0, 1, 0)); + + Basis normal_basis = transform.basis.inverse().transposed(); - Vector<ArrayMeshLightmapSurface> surfaces; for (int i = 0; i < get_surface_count(); i++) { ArrayMeshLightmapSurface s; s.primitive = surface_get_primitive_type(i); @@ -1405,12 +1419,12 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe vertices.resize((vertex_ofs + vc) * 3); normals.resize((vertex_ofs + vc) * 3); - uv_index.resize(vertex_ofs + vc); + uv_indices.resize(vertex_ofs + vc); for (int j = 0; j < vc; j++) { - Vector3 v = p_base_transform.xform(r[j]); - Vector3 n = p_base_transform.basis.xform(rn[j]).normalized(); + Vector3 v = transform.xform(r[j]); + Vector3 n = normal_basis.xform(rn[j]).normalized(); vertices.write[(j + vertex_ofs) * 3 + 0] = v.x; vertices.write[(j + vertex_ofs) * 3 + 1] = v.y; @@ -1418,7 +1432,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe normals.write[(j + vertex_ofs) * 3 + 0] = n.x; normals.write[(j + vertex_ofs) * 3 + 1] = n.y; normals.write[(j + vertex_ofs) * 3 + 2] = n.z; - uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j); + uv_indices.write[j + vertex_ofs] = Pair<int, int>(i, j); } Vector<int> rindices = arrays[Mesh::ARRAY_INDEX]; @@ -1433,7 +1447,6 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe indices.push_back(vertex_ofs + j * 3 + 0); indices.push_back(vertex_ofs + j * 3 + 1); indices.push_back(vertex_ofs + j * 3 + 2); - face_materials.push_back(i); } } else { @@ -1445,11 +1458,10 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe indices.push_back(vertex_ofs + ri[j * 3 + 0]); indices.push_back(vertex_ofs + ri[j * 3 + 1]); indices.push_back(vertex_ofs + ri[j * 3 + 2]); - face_materials.push_back(i); } } - surfaces.push_back(s); + lightmap_surfaces.push_back(s); } //unwrap @@ -1462,7 +1474,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe int size_x; int size_y; - bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y); + bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y, r_cache_data, r_cache_size, r_used_cache); if (!ok) { return ERR_CANT_CREATE; @@ -1474,11 +1486,11 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe //create surfacetools for each surface.. Vector<Ref<SurfaceTool>> surfaces_tools; - for (int i = 0; i < surfaces.size(); i++) { + for (int i = 0; i < lightmap_surfaces.size(); i++) { Ref<SurfaceTool> st; st.instance(); st->begin(Mesh::PRIMITIVE_TRIANGLES); - st->set_material(surfaces[i].material); + st->set_material(lightmap_surfaces[i].material); surfaces_tools.push_back(st); //stay there } @@ -1486,37 +1498,37 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe //go through all indices for (int i = 0; i < gen_index_count; i += 3) { - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG); - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG); - ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_indices.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_indices.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_indices.size(), ERR_BUG); - ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); + ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); - int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first; + int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first; for (int j = 0; j < 3; j++) { - SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second]; + SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; - if (surfaces[surface].format & ARRAY_FORMAT_COLOR) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { surfaces_tools.write[surface]->add_color(v.color); } - if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { surfaces_tools.write[surface]->add_uv(v.uv); } - if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { surfaces_tools.write[surface]->add_normal(v.normal); } - if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { Plane t; t.normal = v.tangent; t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; surfaces_tools.write[surface]->add_tangent(t); } - if (surfaces[surface].format & ARRAY_FORMAT_BONES) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { surfaces_tools.write[surface]->add_bones(v.bones); } - if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { + if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { surfaces_tools.write[surface]->add_weights(v.weights); } @@ -1527,20 +1539,22 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe } } - //free stuff - ::free(gen_vertices); - ::free(gen_indices); - ::free(gen_uvs); - //generate surfaces for (int i = 0; i < surfaces_tools.size(); i++) { surfaces_tools.write[i]->index(); - surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format); + surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format); } set_lightmap_size_hint(Size2(size_x, size_y)); + if (!r_used_cache) { + //free stuff + ::free(gen_vertices); + ::free(gen_indices); + ::free(gen_uvs); + } + return OK; } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 25a9722046..a65cf0a928 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -238,6 +238,7 @@ public: void regen_normalmaps(); Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); + Error lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); virtual void reload_from_file(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 5068bb548f..41146036f6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -120,18 +120,23 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R int index = token.value; - String path = local_path + "::" + itos(index); + if (use_nocache) { + r_res = int_resources[index]; + } else { - if (!ignore_resource_parsing) { + String path = local_path + "::" + itos(index); - if (!ResourceCache::has(path)) { - r_err_str = "Can't load cached sub-resource: " + path; - return ERR_PARSE_ERROR; - } + if (!ignore_resource_parsing) { - r_res = RES(ResourceCache::get(path)); - } else { - r_res = RES(); + if (!ResourceCache::has(path)) { + r_err_str = "Can't load cached sub-resource: " + path; + return ERR_PARSE_ERROR; + } + + r_res = RES(ResourceCache::get(path)); + } else { + r_res = RES(); + } } VariantParser::get_token(p_stream, token, line, r_err_str); @@ -535,7 +540,7 @@ Error ResourceLoaderText::load() { Ref<Resource> res; - if (!ResourceCache::has(path)) { //only if it doesn't exist + if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist Object *obj = ClassDB::instance(type); if (!obj) { @@ -556,8 +561,10 @@ Error ResourceLoaderText::load() { } res = Ref<Resource>(r); - resource_cache.push_back(res); - res->set_path(path); + int_resources[id] = res; + if (!use_nocache) { + res->set_path(path); + } } resource_current++; @@ -643,10 +650,12 @@ Error ResourceLoaderText::load() { _printerr(); } else { error = OK; - if (!ResourceCache::has(res_path)) { - resource->set_path(res_path); + if (!use_nocache) { + if (!ResourceCache::has(res_path)) { + resource->set_path(res_path); + } + resource->set_as_translation_remapped(translation_remapped); } - resource->set_as_translation_remapped(translation_remapped); } return error; } @@ -691,7 +700,7 @@ Error ResourceLoaderText::load() { error = OK; //get it here resource = packed_scene; - if (!ResourceCache::has(res_path)) { + if (!use_nocache && !ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } @@ -725,6 +734,9 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) { } ResourceLoaderText::ResourceLoaderText() { + + use_nocache = false; + resources_total = 0; resource_current = 0; use_sub_threads = false; @@ -1285,7 +1297,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; @@ -1298,6 +1310,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; + loader.use_nocache = p_no_cache; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index fbbd2e3346..b9a6db5f36 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -62,6 +62,7 @@ class ResourceLoaderText { //Map<String,String> remaps; Map<int, ExtResource> ext_resources; + Map<int, RES> int_resources; int resources_total; int resource_current; @@ -69,6 +70,8 @@ class ResourceLoaderText { VariantParser::Tag next_tag; + bool use_nocache; + bool use_sub_threads; float *progress; @@ -106,7 +109,6 @@ class ResourceLoaderText { friend class ResourceFormatLoaderText; - List<RES> resource_cache; Error error; RES resource; @@ -134,7 +136,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index a62e7ded16..1ac2f7c3c9 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -176,7 +176,7 @@ Shader::~Shader() { } //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/shader.h b/scene/resources/shader.h index cf0cec362c..75c38bd561 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 749dff24f2..d57af29599 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -796,7 +796,7 @@ StreamTexture::~StreamTexture() { } } -RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { Ref<StreamTexture> st; st.instance(); @@ -1692,15 +1692,20 @@ void AnimatedTexture::_update_proxy() { } int iter_max = frame_count; - while (iter_max) { + while (iter_max && !pause) { float frame_limit = limit + frames[current_frame].delay_sec; if (time > frame_limit) { current_frame++; if (current_frame >= frame_count) { - current_frame = 0; + if (oneshot) { + current_frame = frame_count - 1; + } else { + current_frame = 0; + } } time -= frame_limit; + _change_notify("current_frame"); } else { break; } @@ -1723,6 +1728,33 @@ int AnimatedTexture::get_frames() const { return frame_count; } +void AnimatedTexture::set_current_frame(int p_frame) { + ERR_FAIL_COND(p_frame < 0 || p_frame >= frame_count); + + RWLockWrite r(rw_lock); + + current_frame = p_frame; +} +int AnimatedTexture::get_current_frame() const { + return current_frame; +} + +void AnimatedTexture::set_pause(bool p_pause) { + RWLockWrite r(rw_lock); + pause = p_pause; +} +bool AnimatedTexture::get_pause() const { + return pause; +} + +void AnimatedTexture::set_oneshot(bool p_oneshot) { + RWLockWrite r(rw_lock); + oneshot = p_oneshot; +} +bool AnimatedTexture::get_oneshot() const { + return oneshot; +} + void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); @@ -1833,6 +1865,15 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames); ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames); + ClassDB::bind_method(D_METHOD("set_current_frame", "frame"), &AnimatedTexture::set_current_frame); + ClassDB::bind_method(D_METHOD("get_current_frame"), &AnimatedTexture::get_current_frame); + + ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause); + ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause); + + ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot); + ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot); + ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps); ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps); @@ -1843,6 +1884,9 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay); ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", 0), "set_current_frame", "get_current_frame"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); for (int i = 0; i < MAX_FRAMES; i++) { @@ -1864,6 +1908,8 @@ AnimatedTexture::AnimatedTexture() { fps = 4; prev_ticks = 0; current_frame = 0; + pause = false; + oneshot = false; RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy)); #ifndef NO_THREADS @@ -2024,7 +2070,7 @@ TextureLayered::~TextureLayered() { } } -RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) { *r_error = ERR_CANT_OPEN; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 18f70baa07..5d5f438eba 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -213,7 +213,7 @@ public: class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -421,7 +421,7 @@ public: COMPRESSION_UNCOMPRESSED }; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -567,7 +567,8 @@ private: Frame frames[MAX_FRAMES]; int frame_count; int current_frame; - + bool pause; + bool oneshot; float fps; float time; @@ -584,6 +585,15 @@ public: void set_frames(int p_frames); int get_frames() const; + void set_current_frame(int p_frame); + int get_current_frame() const; + + void set_pause(bool p_pause); + bool get_pause() const; + + void set_oneshot(bool p_oneshot); + bool get_oneshot() const; + void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture); Ref<Texture2D> get_frame_texture(int p_frame) const; diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 742ef106d9..f2f67d3814 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -314,7 +314,7 @@ struct SpatialIndexer2D { pass = 0; changed = false; - cell_size = 100; //should be configurable with GLOBAL_DEF("") i guess + cell_size = GLOBAL_DEF("world/2d/cell_size", 100); } }; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index da1a68a179..ff8b10cbb6 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -30,7 +30,7 @@ #include "display_server.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "scene/resources/texture.h" DisplayServer *DisplayServer::singleton = nullptr; @@ -164,7 +164,7 @@ float DisplayServer::screen_get_scale(int p_screen) const { bool DisplayServer::screen_is_touchscreen(int p_screen) const { //return false; - return InputFilter::get_singleton() && InputFilter::get_singleton()->is_emulating_touch_from_mouse(); + return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse(); } void DisplayServer::screen_set_keep_on(bool p_enable) { @@ -563,31 +563,31 @@ DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driv return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error); } -void DisplayServer::_input_set_mouse_mode(InputFilter::MouseMode p_mode) { +void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) { singleton->mouse_set_mode(MouseMode(p_mode)); } -InputFilter::MouseMode DisplayServer::_input_get_mouse_mode() { - return InputFilter::MouseMode(singleton->mouse_get_mode()); +Input::MouseMode DisplayServer::_input_get_mouse_mode() { + return Input::MouseMode(singleton->mouse_get_mode()); } void DisplayServer::_input_warp(const Vector2 &p_to_pos) { singleton->mouse_warp_to_position(p_to_pos); } -InputFilter::CursorShape DisplayServer::_input_get_current_cursor_shape() { - return (InputFilter::CursorShape)singleton->cursor_get_shape(); +Input::CursorShape DisplayServer::_input_get_current_cursor_shape() { + return (Input::CursorShape)singleton->cursor_get_shape(); } -void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, InputFilter::CursorShape p_shape, const Vector2 &p_hostspot) { +void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) { singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot); } DisplayServer::DisplayServer() { singleton = this; - InputFilter::set_mouse_mode_func = _input_set_mouse_mode; - InputFilter::get_mouse_mode_func = _input_get_mouse_mode; - InputFilter::warp_mouse_func = _input_warp; - InputFilter::get_current_cursor_shape_func = _input_get_current_cursor_shape; - InputFilter::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func; + Input::set_mouse_mode_func = _input_set_mouse_mode; + Input::get_mouse_mode_func = _input_get_mouse_mode; + Input::warp_mouse_func = _input_warp; + Input::get_current_cursor_shape_func = _input_get_current_cursor_shape; + Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func; } DisplayServer::~DisplayServer() { } diff --git a/servers/display_server.h b/servers/display_server.h index 93db7ef844..f6ba26fc6f 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -32,7 +32,7 @@ #define DISPLAY_SERVER_H #include "core/callable.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/resource.h" @@ -61,11 +61,11 @@ public: typedef Vector<String> (*GetRenderingDriversFunction)(); private: - static void _input_set_mouse_mode(InputFilter::MouseMode p_mode); - static InputFilter::MouseMode _input_get_mouse_mode(); + static void _input_set_mouse_mode(Input::MouseMode p_mode); + static Input::MouseMode _input_get_mouse_mode(); static void _input_warp(const Vector2 &p_to_pos); - static InputFilter::CursorShape _input_get_current_cursor_shape(); - static void _input_set_custom_mouse_cursor_func(const RES &, InputFilter::CursorShape, const Vector2 &p_hostspot); + static Input::CursorShape _input_get_current_cursor_shape(); + static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot); protected: static void _bind_methods(); diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index d8da6e715b..b454dc54af 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -1499,7 +1499,7 @@ void PhysicsServer3DSW::flush_queries() { values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); values.push_front("physics"); - EngineDebugger::profiler_add_frame_data("server", values); + EngineDebugger::profiler_add_frame_data("servers", values); } #endif }; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 556f9cd8e3..60217002fb 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -62,6 +62,10 @@ #include "physics_3d/physics_server_3d_sw.h" #include "physics_server_2d.h" #include "physics_server_3d.h" +#include "rendering/rasterizer.h" +#include "rendering/rendering_device.h" +#include "rendering/rendering_device_binds.h" + #include "rendering_server.h" #include "servers/rendering/shader_types.h" #include "xr/xr_interface.h" @@ -100,18 +104,18 @@ void register_server_types() { ClassDB::register_virtual_class<DisplayServer>(); ClassDB::register_virtual_class<RenderingServer>(); ClassDB::register_class<AudioServer>(); - ClassDB::register_virtual_class<PhysicsServer3D>(); ClassDB::register_virtual_class<PhysicsServer2D>(); + ClassDB::register_virtual_class<PhysicsServer3D>(); + ClassDB::register_virtual_class<NavigationServer2D>(); + ClassDB::register_virtual_class<NavigationServer3D>(); ClassDB::register_class<XRServer>(); ClassDB::register_class<CameraServer>(); + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_virtual_class<XRInterface>(); ClassDB::register_class<XRPositionalTracker>(); - ClassDB::add_compatibility_class("ARVRServer", "XRServer"); - ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); - ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); - ClassDB::register_virtual_class<AudioStream>(); ClassDB::register_virtual_class<AudioStreamPlayback>(); ClassDB::register_virtual_class<AudioStreamPlaybackResampled>(); @@ -161,6 +165,22 @@ void register_server_types() { ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); } + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_class<RDTextureFormat>(); + ClassDB::register_class<RDTextureView>(); + ClassDB::register_class<RDAttachmentFormat>(); + ClassDB::register_class<RDSamplerState>(); + ClassDB::register_class<RDVertexAttribute>(); + ClassDB::register_class<RDUniform>(); + ClassDB::register_class<RDPipelineRasterizationState>(); + ClassDB::register_class<RDPipelineMultisampleState>(); + ClassDB::register_class<RDPipelineDepthStencilState>(); + ClassDB::register_class<RDPipelineColorBlendStateAttachment>(); + ClassDB::register_class<RDPipelineColorBlendState>(); + ClassDB::register_class<RDShaderSource>(); + ClassDB::register_class<RDShaderBytecode>(); + ClassDB::register_class<RDShaderFile>(); + ClassDB::register_class<CameraFeed>(); ClassDB::register_virtual_class<PhysicsDirectBodyState2D>(); @@ -196,6 +216,7 @@ void unregister_server_types() { void register_server_singletons() { + Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton())); diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index 1a21fdb4d7..956bf54d01 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -273,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int Vector<uint8_t> polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); - Vector<RD::VertexDescription> descriptions; + Vector<RD::VertexAttribute> descriptions; descriptions.resize(4); Vector<RID> buffers; buffers.resize(4); @@ -284,7 +284,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int uint32_t *uptr = (uint32_t *)r; uint32_t base_offset = 0; { //vertices - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_VERTEX; @@ -304,7 +304,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //colors if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_COLOR; @@ -332,7 +332,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_COLOR; @@ -344,7 +344,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //uvs if ((uint32_t)p_uvs.size() == vertex_count) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_TEX_UV; @@ -360,7 +360,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 2; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_TEX_UV; @@ -372,7 +372,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //bones if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_BONES; @@ -401,7 +401,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = 0; vd.location = RS::ARRAY_BONES; @@ -2423,8 +2423,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } //pipelines - Vector<RD::VertexDescription> vf; - RD::VertexDescription vd; + Vector<RD::VertexAttribute> vf; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; vd.location = 0; vd.offset = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 97ef604dd2..d32627a076 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -2341,14 +2341,14 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su Mesh::Surface::Version &v = s->versions[version]; - Vector<RD::VertexDescription> attributes; + Vector<RD::VertexAttribute> attributes; Vector<RID> buffers; uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - RD::VertexDescription vd; + RD::VertexAttribute vd; RID buffer; vd.location = i; @@ -5063,10 +5063,10 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: bv[2].z = v.basis.elements[2][2]; bv[2].w = 0; - bv[2].x = v.origin.x; - bv[2].y = v.origin.y; - bv[2].z = v.origin.z; - bv[2].w = 1; + bv[3].x = v.origin.x; + bv[3].y = v.origin.y; + bv[3].z = v.origin.z; + bv[3].w = 1; } break; default: { diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl index b28250318e..b24f7dccc7 100644 --- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl +++ b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl @@ -48,8 +48,8 @@ void main() { frag_color.a = 0.0; #ifdef MODE_SSR - vec4 ssr = texture(ssr, uv_interp); - frag_color.rgb = mix(frag_color.rgb, ssr.rgb, ssr.a); + vec4 ssr_color = texture(ssr, uv_interp); + frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a); #endif #ifdef MODE_MERGE diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index a3799b0e4d..a3bb39cd90 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "rendering_device.h" +#include "core/method_bind_ext.gen.inc" +#include "rendering_device_binds.h" RenderingDevice *RenderingDevice::singleton = nullptr; @@ -59,6 +61,753 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error); } +RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { + + ERR_FAIL_COND_V(p_format.is_null(), RID()); + ERR_FAIL_COND_V(p_view.is_null(), RID()); + Vector<Vector<uint8_t>> data; + for (int i = 0; i < p_data.size(); i++) { + Vector<uint8_t> byte_slice = p_data[i]; + ERR_FAIL_COND_V(byte_slice.empty(), RID()); + data.push_back(byte_slice); + } + return texture_create(p_format->base, p_view->base, data); +} + +RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared(p_view->base, p_with_texture); +} + +RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type); +} + +RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) { + + Vector<AttachmentFormat> attachments; + attachments.resize(p_attachments.size()); + + for (int i = 0; i < p_attachments.size(); i++) { + Ref<RDAttachmentFormat> af = p_attachments[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + attachments.write[i] = af->base; + } + return framebuffer_format_create(attachments); +} + +RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) { + + Vector<RID> textures = Variant(p_textures); + return framebuffer_create(textures, p_format_check); +} + +RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) { + ERR_FAIL_COND_V(p_state.is_null(), RID()); + + return sampler_create(p_state->base); +} + +RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) { + + Vector<VertexAttribute> descriptions; + descriptions.resize(p_vertex_formats.size()); + + for (int i = 0; i < p_vertex_formats.size(); i++) { + Ref<RDVertexAttribute> af = p_vertex_formats[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + descriptions.write[i] = af->base; + } + return vertex_format_create(descriptions); +} + +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) { + + Vector<RID> buffers = Variant(p_src_buffers); + + return vertex_array_create(p_vertex_count, p_vertex_format, buffers); +} + +Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>()); + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error; + + ShaderStage stage = ShaderStage(i); + Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); + bytecode->set_stage_bytecode(stage, spirv); + bytecode->set_stage_compile_error(stage, error); + } + return bytecode; +} + +RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) { + ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); + + Vector<ShaderStageData> stage_data; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + ShaderStage stage = ShaderStage(i); + ShaderStageData sd; + sd.shader_stage = stage; + String error = p_bytecode->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_bytecode->get_stage_bytecode(stage); + if (sd.spir_v.empty()) { + continue; + } + stage_data.push_back(sd); + } + + return shader_create(stage_data); +} + +RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { + + Vector<Uniform> uniforms; + uniforms.resize(p_uniforms.size()); + for (int i = 0; i < p_uniforms.size(); i++) { + Ref<RDUniform> uniform = p_uniforms[i]; + ERR_FAIL_COND_V(!uniform.is_valid(), RID()); + uniforms.write[i] = uniform->base; + } + return uniform_set_create(uniforms, p_shader, p_shader_set); +} + +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { + + return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); +} + +RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { + + PipelineRasterizationState rasterization_state; + if (p_rasterization_state.is_valid()) { + rasterization_state = p_rasterization_state->base; + } + + PipelineMultisampleState multisample_state; + if (p_multisample_state.is_valid()) { + multisample_state = p_multisample_state->base; + for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) { + int64_t mask = p_multisample_state->sample_masks[i]; + multisample_state.sample_mask.push_back(mask); + } + } + + PipelineDepthStencilState depth_stencil_state; + if (p_depth_stencil_state.is_valid()) { + depth_stencil_state = p_depth_stencil_state->base; + } + + PipelineColorBlendState color_blend_state; + if (p_blend_state.is_valid()) { + color_blend_state = p_blend_state->base; + for (int i = 0; i < p_blend_state->attachments.size(); i++) { + Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i]; + if (attachment.is_valid()) { + color_blend_state.attachments.push_back(attachment->base); + } + } + } + + return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags); +} + +Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { + + Vector<DrawListID> splits; + splits.resize(p_splits); + draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region); + + Vector<int64_t> split_ids; + split_ids.resize(splits.size()); + for (int i = 0; i < splits.size(); i++) { + split_ids.write[i] = splits[i]; + } + + return split_ids; +} + +void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_bind_methods() { + + ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); + ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); + + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); + + ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); + + ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); + ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); + + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create); + ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples); + ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID)); + ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); + + ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); + + ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + + ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); + + ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::_shader_create); + ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); + + ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>())); + + ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); + ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); + + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); + + ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create); + ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format); + + ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color())); + + ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + + ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline); + ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array); + ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array); + ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant); + + ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor); + + ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end); + + ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); + ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); + ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); + ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); + ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end); + + ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free); + + ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name); + + ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get); + ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay); + ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); + ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); + + ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); + + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT); + + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D); + + BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST); + BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX); + + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX); + + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX); + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE); + + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16); + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32); + + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO). + BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX); + + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX); + + BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED); + BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT); + BIND_ENUM_CONSTANT(POLYGON_CULL_BACK); + + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE); + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE); + + BIND_ENUM_CONSTANT(STENCIL_OP_KEEP); + BIND_ENUM_CONSTANT(STENCIL_OP_ZERO); + BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_INVERT); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(COMPARE_OP_NEVER); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS); + BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER); + BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS); + BIND_ENUM_CONSTANT(COMPARE_OP_MAX); + + BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR); + BIND_ENUM_CONSTANT(LOGIC_OP_AND); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP); + BIND_ENUM_CONSTANT(LOGIC_OP_XOR); + BIND_ENUM_CONSTANT(LOGIC_OP_OR); + BIND_ENUM_CONSTANT(LOGIC_OP_NOR); + BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT); + BIND_ENUM_CONSTANT(LOGIC_OP_INVERT); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NAND); + BIND_ENUM_CONSTANT(LOGIC_OP_SET); + BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX); + + BIND_ENUM_CONSTANT(BLEND_OP_ADD); + BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAX); + + BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); + + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) + BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it + BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) + BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from) + BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering + BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish" + BIND_ENUM_CONSTANT(FINAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE); + BIND_ENUM_CONSTANT(SHADER_STAGE_MAX); + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT); + + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL); + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL); + + BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE); + BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + + BIND_CONSTANT(INVALID_ID); + BIND_CONSTANT(INVALID_FORMAT_ID); +} + RenderingDevice::RenderingDevice() { - singleton = this; + if (singleton == nullptr) { // there may be more rendering devices later + singleton = this; + } } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 97fe417def..c76fce5b5c 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -32,8 +32,22 @@ #define RENDERING_DEVICE_H #include "core/object.h" +#include "core/typed_array.h" #include "servers/display_server.h" +class RDTextureFormat; +class RDTextureView; +class RDAttachmentFormat; +class RDSamplerState; +class RDVertexAttribute; +class RDShaderSource; +class RDShaderBytecode; +class RDUniforms; +class RDPipelineRasterizationState; +class RDPipelineMultisampleState; +class RDPipelineDepthStencilState; +class RDPipelineColorBlendState; + class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) public: @@ -65,10 +79,14 @@ private: static RenderingDevice *singleton; +protected: + static void _bind_methods(); + public: //base numeric ID for all types enum { - INVALID_ID = -1 + INVALID_ID = -1, + INVALID_FORMAT_ID = -1 }; /*****************/ @@ -530,13 +548,13 @@ public: VERTEX_FREQUENCY_INSTANCE, }; - struct VertexDescription { + struct VertexAttribute { uint32_t location; //shader location uint32_t offset; DataFormat format; uint32_t stride; VertexFrequency frequency; - VertexDescription() { + VertexAttribute() { location = 0; offset = 0; stride = 0; @@ -549,7 +567,7 @@ public: typedef int64_t VertexFormatID; // This ID is warranted to be unique for the same formats, does not need to be freed - virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0; + virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0; virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0; enum IndexBufferFormat { @@ -595,7 +613,7 @@ public: UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO). UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly - UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly + UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly UNIFORM_TYPE_MAX }; @@ -796,8 +814,8 @@ public: } }; - StencilOperationState stencil_operation_front; - StencilOperationState stencil_operation_back; + StencilOperationState front_op; + StencilOperationState back_op; PipelineDepthStencilState() { enable_depth_test = false; @@ -884,8 +902,8 @@ public: DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6), }; - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; virtual bool render_pipeline_is_valid(RID p_pipeline) = 0; + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; /**************************/ /**** COMPUTE PIPELINE ****/ @@ -932,7 +950,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0; virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0; virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0; - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0; @@ -950,7 +968,7 @@ public: virtual ComputeListID compute_list_begin() = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; @@ -1024,10 +1042,67 @@ public: virtual uint32_t get_frame_delay() const = 0; + virtual void submit() = 0; + virtual void sync() = 0; + + virtual RenderingDevice *create_local_device() = 0; + static RenderingDevice *get_singleton(); RenderingDevice(); + +protected: + //binders to script API + RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array()); + RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture); + RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); + + FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments); + RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID); + RID _sampler_create(const Ref<RDSamplerState> &p_state); + VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); + + Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode); + + RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); + + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + + RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0); + + Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); + void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); }; +VARIANT_ENUM_CAST(RenderingDevice::ShaderStage) +VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage) +VARIANT_ENUM_CAST(RenderingDevice::CompareOperator) +VARIANT_ENUM_CAST(RenderingDevice::DataFormat) +VARIANT_ENUM_CAST(RenderingDevice::TextureType) +VARIANT_ENUM_CAST(RenderingDevice::TextureSamples) +VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits) +VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle) +VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType) +VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter) +VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode) +VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor) +VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency) +VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat) +VARIANT_ENUM_CAST(RenderingDevice::UniformType) +VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive) +VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode) +VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace) +VARIANT_ENUM_CAST(RenderingDevice::StencilOperation) +VARIANT_ENUM_CAST(RenderingDevice::LogicOperation) +VARIANT_ENUM_CAST(RenderingDevice::BlendFactor) +VARIANT_ENUM_CAST(RenderingDevice::BlendOperation) +VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) +VARIANT_ENUM_CAST(RenderingDevice::InitialAction) +VARIANT_ENUM_CAST(RenderingDevice::FinalAction) +VARIANT_ENUM_CAST(RenderingDevice::Limit) + typedef RenderingDevice RD; #endif // RENDERING_DEVICE_H diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp new file mode 100644 index 0000000000..111755eba3 --- /dev/null +++ b/servers/rendering/rendering_device_binds.cpp @@ -0,0 +1,167 @@ +#include "rendering_device_binds.h" + +Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { + + Vector<String> lines = p_text.split("\n"); + + bool reading_versions = false; + bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false }; + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute" + }; + String stage_code[RD::SHADER_STAGE_MAX]; + int stages_found = 0; + Map<StringName, String> version_texts; + + versions.clear(); + base_error = ""; + + for (int lidx = 0; lidx < lines.size(); lidx++) { + String line = lines[lidx]; + + { + String ls = line.strip_edges(); + if (ls.begins_with("[") && ls.ends_with("]")) { + String section = ls.substr(1, ls.length() - 2).strip_edges(); + if (section == "versions") { + if (stages_found) { + base_error = "Invalid shader file, [version] must be the first section found."; + break; + } + reading_versions = true; + } else { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (section == stage_str[i]) { + if (stage_found[i]) { + base_error = "Invalid shader file, stage appears twice: " + section; + break; + } + + stage_found[i] = true; + stages_found++; + + stage = RD::ShaderStage(i); + reading_versions = false; + break; + } + } + + if (base_error != String()) { + break; + } + } + + continue; + } + } + + if (reading_versions) { + String l = line.strip_edges(); + if (l != "") { + int eqpos = l.find("="); + if (eqpos == -1) { + base_error = "Version syntax is version=\"<defines with C escaping>\"."; + break; + } + String version = l.get_slice("=", 0).strip_edges(); + if (!version.is_valid_identifier()) { + base_error = "Version names must be valid identifiers, found '" + version + "' instead."; + break; + } + String define = l.get_slice("=", 1).strip_edges(); + if (!define.begins_with("\"") || !define.ends_with("\"")) { + base_error = "Version text must be quoted using \"\", instead found '" + define + "'."; + break; + } + define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; //add newline before and after jsut in case + + version_texts[version] = define; + } + } else { + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + base_error = "Text was found that does not belong to a valid section: " + line; + break; + } + + if (stage != RD::SHADER_STAGE_MAX) { + if (line.strip_edges().begins_with("#include")) { + if (p_include_func) { + //process include + String include = line.replace("#include", "").strip_edges(); + if (!include.begins_with("\"") || !include.ends_with("\"")) { + base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include; + break; + } + include = include.substr(1, include.length() - 2).strip_edges(); + String include_text = p_include_func(include, p_include_func_userdata); + if (include_text != String()) { + stage_code[stage] += "\n" + include_text + "\n"; + } else { + base_error = "#include failed for file '" + include + "'"; + } + } else { + base_error = "#include used, but no include function provided."; + } + } else { + + stage_code[stage] += line + "\n"; + } + } + } + } + + Ref<RDShaderFile> shader_file; + shader_file.instance(); + + if (base_error == "") { + + if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) { + ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present."); + } + + if (version_texts.empty()) { + version_texts[""] = ""; //make sure a default version exists + } + + bool errors_found = false; + + /* STEP 2, Compile the versions, add to shader file */ + + for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String code = stage_code[i]; + if (code == String()) { + continue; + } + code = code.replace("VERSION_DEFINES", E->get()); + String error; + Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); + bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); + if (error != "") { + error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n"; + Vector<String> sclines = code.split("\n"); + for (int j = 0; j < sclines.size(); j++) { + error += itos(j + 1) + "\t\t" + sclines[j] + "\n"; + } + errors_found = true; + } + bytecode->set_stage_compile_error(RD::ShaderStage(i), error); + } + + set_bytecode(bytecode, E->key()); + } + + return errors_found ? ERR_PARSE_ERROR : OK; + } else { + return ERR_PARSE_ERROR; + } +} diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h new file mode 100644 index 0000000000..f57f59876d --- /dev/null +++ b/servers/rendering/rendering_device_binds.h @@ -0,0 +1,579 @@ +#ifndef RENDERING_DEVICE_BINDS_H +#define RENDERING_DEVICE_BINDS_H + +#include "servers/rendering/rendering_device.h" + +#define RD_SETGET(m_type, m_member) \ + void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \ + m_type get_##m_member() const { return base.m_member; } + +#define RD_BIND(m_variant_type, m_class, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member)) + +#define RD_SETGET_SUB(m_type, m_sub, m_member) \ + void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \ + m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; } + +#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member)) + +class RDTextureFormat : public Reference { + GDCLASS(RDTextureFormat, Reference) + friend class RenderingDevice; + + RD::TextureFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, width) + RD_SETGET(uint32_t, height) + RD_SETGET(uint32_t, depth) + RD_SETGET(uint32_t, array_layers) + RD_SETGET(uint32_t, mipmaps) + RD_SETGET(RD::TextureType, type) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_bits) + + void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); } + void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureFormat, format); + RD_BIND(Variant::INT, RDTextureFormat, width); + RD_BIND(Variant::INT, RDTextureFormat, height); + RD_BIND(Variant::INT, RDTextureFormat, depth); + RD_BIND(Variant::INT, RDTextureFormat, array_layers); + RD_BIND(Variant::INT, RDTextureFormat, mipmaps); + RD_BIND(Variant::INT, RDTextureFormat, type); + RD_BIND(Variant::INT, RDTextureFormat, samples); + RD_BIND(Variant::INT, RDTextureFormat, usage_bits); + ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format); + ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format); + } +}; + +class RDTextureView : public Reference { + GDCLASS(RDTextureView, Reference) + + friend class RenderingDevice; + + RD::TextureView base; + +public: + RD_SETGET(RD::DataFormat, format_override) + RD_SETGET(RD::TextureSwizzle, swizzle_r) + RD_SETGET(RD::TextureSwizzle, swizzle_g) + RD_SETGET(RD::TextureSwizzle, swizzle_b) + RD_SETGET(RD::TextureSwizzle, swizzle_a) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureView, format_override); + RD_BIND(Variant::INT, RDTextureView, swizzle_r); + RD_BIND(Variant::INT, RDTextureView, swizzle_g); + RD_BIND(Variant::INT, RDTextureView, swizzle_b); + RD_BIND(Variant::INT, RDTextureView, swizzle_a); + } +}; + +class RDAttachmentFormat : public Reference { + GDCLASS(RDAttachmentFormat, Reference) + friend class RenderingDevice; + + RD::AttachmentFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_flags) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDAttachmentFormat, format); + RD_BIND(Variant::INT, RDAttachmentFormat, samples); + RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags); + } +}; + +class RDSamplerState : public Reference { + GDCLASS(RDSamplerState, Reference) + friend class RenderingDevice; + + RD::SamplerState base; + +public: + RD_SETGET(RD::SamplerFilter, mag_filter) + RD_SETGET(RD::SamplerFilter, min_filter) + RD_SETGET(RD::SamplerFilter, mip_filter) + RD_SETGET(RD::SamplerRepeatMode, repeat_u) + RD_SETGET(RD::SamplerRepeatMode, repeat_v) + RD_SETGET(RD::SamplerRepeatMode, repeat_w) + RD_SETGET(float, lod_bias) + RD_SETGET(bool, use_anisotropy) + RD_SETGET(float, anisotropy_max) + RD_SETGET(bool, enable_compare) + RD_SETGET(RD::CompareOperator, compare_op) + RD_SETGET(float, min_lod) + RD_SETGET(float, max_lod) + RD_SETGET(RD::SamplerBorderColor, border_color) + RD_SETGET(bool, unnormalized_uvw) + +protected: + static void _bind_methods() { + + RD_BIND(Variant::INT, RDSamplerState, mag_filter); + RD_BIND(Variant::INT, RDSamplerState, min_filter); + RD_BIND(Variant::INT, RDSamplerState, mip_filter); + RD_BIND(Variant::INT, RDSamplerState, repeat_u); + RD_BIND(Variant::INT, RDSamplerState, repeat_v); + RD_BIND(Variant::INT, RDSamplerState, repeat_w); + RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias); + RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy); + RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max); + RD_BIND(Variant::BOOL, RDSamplerState, enable_compare); + RD_BIND(Variant::INT, RDSamplerState, compare_op); + RD_BIND(Variant::FLOAT, RDSamplerState, min_lod); + RD_BIND(Variant::FLOAT, RDSamplerState, max_lod); + RD_BIND(Variant::INT, RDSamplerState, border_color); + RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw); + } +}; + +class RDVertexAttribute : public Reference { + GDCLASS(RDVertexAttribute, Reference) + friend class RenderingDevice; + RD::VertexAttribute base; + +public: + RD_SETGET(uint32_t, location) + RD_SETGET(uint32_t, offset) + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, stride) + RD_SETGET(RD::VertexFrequency, frequency) + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDVertexAttribute, location); + RD_BIND(Variant::INT, RDVertexAttribute, offset); + RD_BIND(Variant::INT, RDVertexAttribute, format); + RD_BIND(Variant::INT, RDVertexAttribute, stride); + RD_BIND(Variant::INT, RDVertexAttribute, frequency); + } +}; +class RDShaderSource : public Reference { + GDCLASS(RDShaderSource, Reference) + String source[RD::SHADER_STAGE_MAX]; + RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL; + +public: + void set_stage_source(RD::ShaderStage p_stage, const String &p_source) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + source[p_stage] = p_source; + } + + String get_stage_source(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return source[p_stage]; + } + + void set_language(RD::ShaderLanguage p_language) { + language = p_language; + } + + RD::ShaderLanguage get_language() const { + return language; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source); + ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source); + + ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language); + ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language); + + ADD_GROUP("Source", "source_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Syntax", "source_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language"); + } +}; + +class RDShaderBytecode : public Resource { + GDCLASS(RDShaderBytecode, Resource) + + Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX]; + String compile_error[RD::SHADER_STAGE_MAX]; + +public: + void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + bytecode[p_stage] = p_bytecode; + } + + Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>()); + return bytecode[p_stage]; + } + + void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + compile_error[p_stage] = p_compile_error; + } + + String get_stage_compile_error(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return compile_error[p_stage]; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode); + ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode); + + ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error); + ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error); + + ADD_GROUP("Bytecode", "bytecode_"); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Compile Error", "compile_error_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE); + } +}; + +class RDShaderFile : public Resource { + GDCLASS(RDShaderFile, Resource) + + Map<StringName, Ref<RDShaderBytecode>> versions; + String base_error; + +public: + void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) { + ERR_FAIL_COND(p_bytecode.is_null()); + versions[p_version] = p_bytecode; + emit_changed(); + } + + Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>()); + return versions[p_version]; + } + + Vector<StringName> get_version_list() const { + Vector<StringName> vnames; + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + vnames.push_back(E->key()); + } + vnames.sort_custom<StringName::AlphCompare>(); + return vnames; + } + + void set_base_error(const String &p_error) { + base_error = p_error; + emit_changed(); + } + + String get_base_error() const { + return base_error; + } + + typedef String (*OpenIncludeFunction)(const String &, void *userdata); + Error parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); + +protected: + Dictionary _get_versions() const { + Vector<StringName> vnames = get_version_list(); + Dictionary ret; + for (int i = 0; i < vnames.size(); i++) { + ret[vnames[i]] = versions[vnames[i]]; + } + return ret; + } + void _set_versions(const Dictionary &p_versions) { + versions.clear(); + List<Variant> keys; + p_versions.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + StringName name = E->get(); + Ref<RDShaderBytecode> bc = p_versions[E->get()]; + ERR_CONTINUE(bc.is_null()); + versions[name] = bc; + } + + emit_changed(); + } + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list); + + ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error); + ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error); + + ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions); + ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error"); + } +}; + +class RDUniform : public Reference { + GDCLASS(RDUniform, Reference) + friend class RenderingDevice; + RD::Uniform base; + +public: + RD_SETGET(RD::UniformType, type) + RD_SETGET(int32_t, binding) + + void add_id(const RID &p_id) { base.ids.push_back(p_id); } + void clear_ids() { base.ids.clear(); } + Array get_ids() const { + Array ids; + for (int i = 0; i < base.ids.size(); i++) { + ids.push_back(base.ids[i]); + } + return ids; + } + +protected: + void _set_ids(const Array &p_ids) { + base.ids.clear(); + for (int i = 0; i < p_ids.size(); i++) { + RID id = p_ids[i]; + ERR_FAIL_COND(id.is_null()); + base.ids.push_back(id); + } + } + static void _bind_methods() { + RD_BIND(Variant::INT, RDUniform, type); + RD_BIND(Variant::INT, RDUniform, binding); + ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id); + ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids); + ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids); + ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids"); + } +}; +class RDPipelineRasterizationState : public Reference { + GDCLASS(RDPipelineRasterizationState, Reference) + friend class RenderingDevice; + + RD::PipelineRasterizationState base; + +public: + RD_SETGET(bool, enable_depth_clamp) + RD_SETGET(bool, discard_primitives) + RD_SETGET(bool, wireframe) + RD_SETGET(RD::PolygonCullMode, cull_mode) + RD_SETGET(RD::PolygonFrontFace, front_face) + RD_SETGET(bool, depth_bias_enable) + RD_SETGET(float, depth_bias_constant_factor) + RD_SETGET(float, depth_bias_clamp) + RD_SETGET(float, depth_bias_slope_factor) + RD_SETGET(float, line_width) + RD_SETGET(uint32_t, patch_control_points) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe); + RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode); + RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width); + RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points); + } +}; + +class RDPipelineMultisampleState : public Reference { + GDCLASS(RDPipelineMultisampleState, Reference) + friend class RenderingDevice; + + RD::PipelineMultisampleState base; + TypedArray<int64_t> sample_masks; + +public: + RD_SETGET(RD::TextureSamples, sample_count) + RD_SETGET(bool, enable_sample_shading) + RD_SETGET(float, min_sample_shading) + RD_SETGET(bool, enable_alpha_to_coverage) + RD_SETGET(bool, enable_alpha_to_one) + + void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; } + TypedArray<int64_t> get_sample_masks() const { return sample_masks; } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading); + RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one); + + ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks); + ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks"); + } +}; + +class RDPipelineDepthStencilState : public Reference { + GDCLASS(RDPipelineDepthStencilState, Reference) + friend class RenderingDevice; + + RD::PipelineDepthStencilState base; + +public: + RD_SETGET(bool, enable_depth_test) + RD_SETGET(bool, enable_depth_write) + RD_SETGET(RD::CompareOperator, depth_compare_operator) + RD_SETGET(bool, enable_depth_range) + RD_SETGET(float, depth_range_min) + RD_SETGET(float, depth_range_max) + RD_SETGET(bool, enable_stencil) + + RD_SETGET_SUB(RD::StencilOperation, front_op, fail) + RD_SETGET_SUB(RD::StencilOperation, front_op, pass) + RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, front_op, compare) + RD_SETGET_SUB(uint32_t, front_op, compare_mask) + RD_SETGET_SUB(uint32_t, front_op, write_mask) + RD_SETGET_SUB(uint32_t, front_op, reference) + + RD_SETGET_SUB(RD::StencilOperation, back_op, fail) + RD_SETGET_SUB(RD::StencilOperation, back_op, pass) + RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, back_op, compare) + RD_SETGET_SUB(uint32_t, back_op, compare_mask) + RD_SETGET_SUB(uint32_t, back_op, write_mask) + RD_SETGET_SUB(uint32_t, back_op, reference) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write); + RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference); + } +}; + +class RDPipelineColorBlendStateAttachment : public Reference { + GDCLASS(RDPipelineColorBlendStateAttachment, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState::Attachment base; + +public: + RD_SETGET(bool, enable_blend) + RD_SETGET(RD::BlendFactor, src_color_blend_factor) + RD_SETGET(RD::BlendFactor, dst_color_blend_factor) + RD_SETGET(RD::BlendOperation, color_blend_op) + RD_SETGET(RD::BlendFactor, src_alpha_blend_factor) + RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor) + RD_SETGET(RD::BlendOperation, alpha_blend_op) + RD_SETGET(bool, write_r) + RD_SETGET(bool, write_g) + RD_SETGET(bool, write_b) + RD_SETGET(bool, write_a) + + void set_as_mix() { + + base = RD::PipelineColorBlendState::Attachment(); + base.enable_blend = true; + base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + } + +protected: + static void _bind_methods() { + + ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix); + + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a); + } +}; + +class RDPipelineColorBlendState : public Reference { + GDCLASS(RDPipelineColorBlendState, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState base; + + TypedArray<RDPipelineColorBlendStateAttachment> attachments; + +public: + RD_SETGET(bool, enable_logic_op) + RD_SETGET(RD::LogicOperation, logic_op) + RD_SETGET(Color, blend_constant) + + void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) { + attachments.push_back(p_attachments); + } + + TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const { + return attachments; + } + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op); + RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op); + RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant); + + ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments); + ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments"); + } +}; + +#endif // RENDERING_DEVICE_BINDS_H diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0d3b44c0dc..57a34f24cf 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1998,9 +1998,6 @@ void RenderingServer::_bind_methods() { BIND_CONSTANT(MAX_GLOW_LEVELS); BIND_CONSTANT(MAX_CURSORS); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); - BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY); @@ -2018,6 +2015,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(SHADER_SKY); BIND_ENUM_CONSTANT(SHADER_MAX); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); BIND_ENUM_CONSTANT(ARRAY_NORMAL); BIND_ENUM_CONSTANT(ARRAY_TANGENT); @@ -2045,9 +2045,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); @@ -2070,6 +2071,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR); BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION); @@ -2080,6 +2082,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START); 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_BLUR); + BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); @@ -2095,6 +2100,12 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE); BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX); + BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_LIFETIME); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_VIEW_DEPTH); @@ -2114,6 +2125,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X); + BIND_ENUM_CONSTANT(VIEWPORT_MSAA_MAX); + + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_MAX); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME); @@ -2138,6 +2154,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(SKY_MODE_QUALITY); BIND_ENUM_CONSTANT(SKY_MODE_REALTIME); @@ -2170,6 +2187,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2); @@ -2180,6 +2202,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_LOW); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_HIGH); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_VERY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); @@ -2189,6 +2216,13 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(DOF_BOKEH_HEXAGON); BIND_ENUM_CONSTANT(DOF_BOKEH_CIRCLE); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_ULTRA); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_MAX); + BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW); @@ -2201,6 +2235,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(INSTANCE_PARTICLES); BIND_ENUM_CONSTANT(INSTANCE_LIGHT); BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE); + BIND_ENUM_CONSTANT(INSTANCE_DECAL); BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE); BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE); BIND_ENUM_CONSTANT(INSTANCE_MAX); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 3bc182a16b..8ca070b4a9 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -86,7 +86,6 @@ public: }; enum CubeMapLayer { - CUBEMAP_LAYER_LEFT, CUBEMAP_LAYER_RIGHT, CUBEMAP_LAYER_BOTTOM, @@ -158,7 +157,6 @@ public: /* SHADER API */ enum ShaderMode { - SHADER_SPATIAL, SHADER_CANVAS_ITEM, SHADER_PARTICLES, @@ -182,8 +180,8 @@ public: enum { MATERIAL_RENDER_PRIORITY_MIN = -128, MATERIAL_RENDER_PRIORITY_MAX = 127, - }; + virtual RID material_create() = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -198,7 +196,6 @@ public: /* MESH API */ enum ArrayType { - ARRAY_VERTEX = 0, ARRAY_NORMAL = 1, ARRAY_TANGENT = 2, @@ -230,12 +227,10 @@ public: ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2, ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 - }; enum PrimitiveType { @@ -378,7 +373,6 @@ public: }; enum LightParam { - LIGHT_PARAM_ENERGY, LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, @@ -599,7 +593,8 @@ public: }; virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0; -*/ + */ + /* VIEWPORT TARGET API */ virtual RID viewport_create() = 0; @@ -623,7 +618,6 @@ public: virtual void viewport_set_update_mode(RID p_viewport, ViewportUpdateMode p_mode) = 0; enum ViewportClearMode { - VIEWPORT_CLEAR_ALWAYS, VIEWPORT_CLEAR_NEVER, VIEWPORT_CLEAR_ONLY_NEXT_FRAME @@ -664,18 +658,19 @@ public: enum ViewportScreenSpaceAA { VIEWPORT_SCREEN_SPACE_AA_DISABLED, VIEWPORT_SCREEN_SPACE_AA_FXAA, + VIEWPORT_SCREEN_SPACE_AA_MAX, }; + virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0; enum ViewportRenderInfo { - VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME, VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME, VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME, - VIEWPORT_RENDER_INFO_MAX + VIEWPORT_RENDER_INFO_MAX, }; virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0; @@ -697,7 +692,6 @@ public: VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER, VIEWPORT_DEBUG_DRAW_PSSM_SPLITS, VIEWPORT_DEBUG_DRAW_DECAL_ATLAS, - }; virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0; @@ -725,7 +719,6 @@ public: virtual RID environment_create() = 0; enum EnvironmentBG { - ENV_BG_CLEAR_COLOR, ENV_BG_COLOR, ENV_BG_SKY, @@ -768,6 +761,7 @@ public: ENV_GLOW_BLEND_MODE_REPLACE, ENV_GLOW_BLEND_MODE_MIX, }; + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; @@ -872,7 +866,6 @@ public: SCENARIO_DEBUG_WIREFRAME, SCENARIO_DEBUG_OVERDRAW, SCENARIO_DEBUG_SHADELESS, - }; virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0; @@ -883,7 +876,6 @@ public: /* INSTANCING API */ enum InstanceType { - INSTANCE_NONE, INSTANCE_MESH, INSTANCE_MULTIMESH, @@ -1094,6 +1086,7 @@ public: CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0; /* GLOBAL VARIABLES */ @@ -1167,7 +1160,6 @@ public: /* STATUS INFORMATION */ enum RenderInfo { - INFO_OBJECTS_IN_FRAME, INFO_VERTICES_IN_FRAME, INFO_MATERIAL_CHANGES_IN_FRAME, @@ -1250,6 +1242,7 @@ VARIANT_ENUM_CAST(RenderingServer::ParticlesDrawOrder); VARIANT_ENUM_CAST(RenderingServer::ViewportUpdateMode); VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode); VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA); +VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA); VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo); VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw); VARIANT_ENUM_CAST(RenderingServer::SkyMode); @@ -1258,10 +1251,13 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode); VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper); -VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOBlur); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::SubSurfaceScatteringQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBlurQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBokehShape); +VARIANT_ENUM_CAST(RenderingServer::ShadowQuality); VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode); VARIANT_ENUM_CAST(RenderingServer::InstanceType); VARIANT_ENUM_CAST(RenderingServer::InstanceFlags); @@ -1276,7 +1272,7 @@ VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); VARIANT_ENUM_CAST(RenderingServer::RenderInfo); VARIANT_ENUM_CAST(RenderingServer::Features); -//typedef RenderingServer VS; // makes it easier to use +// Alias to make it easier to use. #define RS RenderingServer -#endif +#endif // RENDERING_SERVER_H diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index 808b0a608f..20853c9027 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -29,7 +29,8 @@ /*************************************************************************/ #include "xr_positional_tracker.h" -#include "core/input/input_filter.h" + +#include "core/input/input.h" void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN); diff --git a/thirdparty/README.md b/thirdparty/README.md index 95a6902089..7518f5d0f7 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -40,9 +40,12 @@ Files extracted from upstream source: ## bullet - Upstream: https://github.com/bulletphysics/bullet3 -- Version: 2.89 +- Version: 2.90 (master cd8cf7521cbb8b7808126a6adebd47bb83ea166a) - License: zlib +Important: Synced with a pre-release version of bullet 2.90 from the master branch. +Commit hash: cd8cf7521cbb8b7808126a6adebd47bb83ea166a + Files extracted from upstream source: - src/* apart from CMakeLists.txt and premake4.lua files @@ -182,12 +185,14 @@ Patches in the `patches` directory should be re-applied after updates. ## jpeg-compressor - Upstream: https://github.com/richgel999/jpeg-compressor -- Version: 1.04 +- Version: 2.00 (1eb17d558b9d3b7442d256642a5745974e9eeb1e, 2020) - License: Public domain Files extracted from upstream source: -- `jpgd.{c,h}` +- `jpgd*.{c,h}` + +Patches in the `patches` directory should be re-applied after updates. ## libogg @@ -302,7 +307,7 @@ changes are marked with `// -- GODOT --` comments. ## mbedtls - Upstream: https://tls.mbed.org/ -- Version: 2.16.5 +- Version: 2.16.6 - License: Apache 2.0 File extracted from upstream release tarball (`-apache.tgz` variant): diff --git a/thirdparty/basis_universal/basisu_enc.h b/thirdparty/basis_universal/basisu_enc.h index c2b9133045..0a0c3c6fc0 100644 --- a/thirdparty/basis_universal/basisu_enc.h +++ b/thirdparty/basis_universal/basisu_enc.h @@ -22,6 +22,7 @@ #include <functional> #include <thread> #include <unordered_map> +#include <ostream> #if !defined(_WIN32) || defined(__MINGW32__) #include <libgen.h> diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h index 980d19a754..55daa7fb57 100644 --- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h +++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h @@ -203,8 +203,8 @@ struct btDbvntNode btDbvntNode(const btDbvtNode* n) : volume(n->volume) - , angle(0) , normal(0,0,0) + , angle(0) , data(n->data) { childs[0] = 0; diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h index f4a2d5e368..56011899cb 100644 --- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h +++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -61,7 +61,8 @@ public: virtual void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) = 0; virtual int getNumOverlappingPairs() const = 0; - + virtual bool needsBroadphaseCollision(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1) const = 0; + virtual btOverlapFilterCallback* getOverlapFilterCallback() = 0; virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) = 0; virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0; @@ -380,6 +381,14 @@ public: { } + bool needsBroadphaseCollision(btBroadphaseProxy*, btBroadphaseProxy*) const + { + return true; + } + btOverlapFilterCallback* getOverlapFilterCallback() + { + return 0; + } virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/) { } diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp index b814fd84d8..4954e773e2 100644 --- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp +++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp @@ -468,7 +468,7 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall #ifdef RAYAABB2 btVector3 rayDir = (rayTarget - raySource); - rayDir.normalize(); + rayDir.safeNormalize();// stephengold changed normalize to safeNormalize 2020-02-17 lambda_max = rayDir.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 btVector3 rayDirectionInverse; @@ -554,7 +554,7 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* #ifdef RAYAABB2 btVector3 rayDirection = (rayTarget - raySource); - rayDirection.normalize(); + rayDirection.safeNormalize();// stephengold changed normalize to safeNormalize 2020-02-17 lambda_max = rayDirection.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0]; diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h index 6b9f5e23a5..04309670cf 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h @@ -46,8 +46,6 @@ protected: btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr; - btManifoldResult m_defaultManifoldResult; - btNearCallback m_nearCallback; btPoolAllocator* m_collisionAlgorithmPoolAllocator; @@ -95,11 +93,15 @@ public: btPersistentManifold* getManifoldByIndexInternal(int index) { + btAssert(index>=0); + btAssert(index<m_manifoldsPtr.size()); return m_manifoldsPtr[index]; } const btPersistentManifold* getManifoldByIndexInternal(int index) const { + btAssert(index>=0); + btAssert(index<m_manifoldsPtr.size()); return m_manifoldsPtr[index]; } diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp index 6fe56538d2..89bc8d920e 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp @@ -28,6 +28,7 @@ subject to the following restrictions: btCollisionDispatcherMt::btCollisionDispatcherMt(btCollisionConfiguration* config, int grainSize) : btCollisionDispatcher(config) { + m_batchManifoldsPtr.resize(btGetTaskScheduler()->getNumThreads()); m_batchUpdating = false; m_grainSize = grainSize; // iterations per task } @@ -65,6 +66,10 @@ btPersistentManifold* btCollisionDispatcherMt::getNewManifold(const btCollisionO manifold->m_index1a = m_manifoldsPtr.size(); m_manifoldsPtr.push_back(manifold); } + else + { + m_batchManifoldsPtr[btGetCurrentThreadIndex()].push_back(manifold); + } return manifold; } @@ -121,7 +126,7 @@ struct CollisionDispatcherUpdater : public btIParallelForBody void btCollisionDispatcherMt::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher) { - int pairCount = pairCache->getNumOverlappingPairs(); + const int pairCount = pairCache->getNumOverlappingPairs(); if (pairCount == 0) { return; @@ -136,16 +141,17 @@ void btCollisionDispatcherMt::dispatchAllCollisionPairs(btOverlappingPairCache* btParallelFor(0, pairCount, m_grainSize, updater); m_batchUpdating = false; - // reconstruct the manifolds array to ensure determinism - m_manifoldsPtr.resizeNoInitialize(0); - - btBroadphasePair* pairs = pairCache->getOverlappingPairArrayPtr(); - for (int i = 0; i < pairCount; ++i) + // merge new manifolds, if any + for (int i = 0; i < m_batchManifoldsPtr.size(); ++i) { - if (btCollisionAlgorithm* algo = pairs[i].m_algorithm) + btAlignedObjectArray<btPersistentManifold*>& batchManifoldsPtr = m_batchManifoldsPtr[i]; + + for (int j = 0; j < batchManifoldsPtr.size(); ++j) { - algo->getAllContactManifolds(m_manifoldsPtr); + m_manifoldsPtr.push_back(batchManifoldsPtr[j]); } + + batchManifoldsPtr.resizeNoInitialize(0); } // update the indices (used when releasing manifolds) diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h index 28eba7f32a..1155de2cfe 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h @@ -30,6 +30,7 @@ public: virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher) BT_OVERRIDE; protected: + btAlignedObjectArray<btAlignedObjectArray<btPersistentManifold*> > m_batchManifoldsPtr; bool m_batchUpdating; int m_grainSize; }; diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp index 1bb21104cb..b5f4a3c869 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -139,7 +139,12 @@ public: if (TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1)) { - btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap, childShape, m_compoundColObjWrap->getCollisionObject(), newChildWorldTrans, childTrans, -1, index); + btTransform preTransform = childTrans; + if (this->m_compoundColObjWrap->m_preTransform) + { + preTransform = preTransform *(*(this->m_compoundColObjWrap->m_preTransform)); + } + btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap, childShape, m_compoundColObjWrap->getCollisionObject(), newChildWorldTrans, preTransform, -1, index); btCollisionAlgorithm* algo = 0; bool allocatedAlgorithm = false; diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index e82d1b139e..4356c12abf 100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -46,7 +46,7 @@ struct btContactSolverInfoData btScalar m_sor; //successive over-relaxation term btScalar m_erp; //error reduction for non-contact constraints btScalar m_erp2; //error reduction for contact constraints - btScalar m_deformable_erp; //error reduction for deformable constraints + btScalar m_deformable_erp; //error reduction for deformable constraints btScalar m_globalCfm; //constraint force mixing for contacts and non-contacts btScalar m_frictionERP; //error reduction for friction constraints btScalar m_frictionCFM; //constraint force mixing for friction constraints @@ -67,6 +67,7 @@ struct btContactSolverInfoData bool m_jointFeedbackInWorldSpace; bool m_jointFeedbackInJointFrame; int m_reportSolverAnalytics; + int m_numNonContactInnerIterations; }; struct btContactSolverInfo : public btContactSolverInfoData @@ -82,7 +83,7 @@ struct btContactSolverInfo : public btContactSolverInfoData m_numIterations = 10; m_erp = btScalar(0.2); m_erp2 = btScalar(0.2); - m_deformable_erp = btScalar(0.); + m_deformable_erp = btScalar(0.1); m_globalCfm = btScalar(0.); m_frictionERP = btScalar(0.2); //positional friction 'anchors' are disabled by default m_frictionCFM = btScalar(0.); @@ -104,6 +105,7 @@ struct btContactSolverInfo : public btContactSolverInfoData m_jointFeedbackInWorldSpace = false; m_jointFeedbackInJointFrame = false; m_reportSolverAnalytics = 0; + m_numNonContactInnerIterations = 1; // the number of inner iterations for solving motor constraint in a single iteration of the constraint solve } }; diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp index 93626f18ff..74a13c6249 100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp @@ -876,7 +876,10 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( // will we not request a velocity with the wrong direction ? // and the answer is not, because in practice during the solving the current velocity is subtracted from the m_constraintError // so the sign of the force that is really matters - info->m_constraintError[srow] = (rotational ? -1 : 1) * (f < 0 ? -SIMD_INFINITY : SIMD_INFINITY); + if (m_flags & BT_6DOF_FLAGS_USE_INFINITE_ERROR) + info->m_constraintError[srow] = (rotational ? -1 : 1) * (f < 0 ? -SIMD_INFINITY : SIMD_INFINITY); + else + info->m_constraintError[srow] = vel + f / m * (rotational ? -1 : 1); btScalar minf = f < fd ? f : fd; btScalar maxf = f < fd ? fd : f; diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h index 00e24364e0..c86dc373da 100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h @@ -265,6 +265,7 @@ enum bt6DofFlags2 BT_6DOF_FLAGS_ERP_STOP2 = 2, BT_6DOF_FLAGS_CFM_MOTO2 = 4, BT_6DOF_FLAGS_ERP_MOTO2 = 8, + BT_6DOF_FLAGS_USE_INFINITE_ERROR = (1<<16) }; #define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index e4da468299..d2641c582f 100644 --- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -14,7 +14,9 @@ subject to the following restrictions: */ //#define COMPUTE_IMPULSE_DENOM 1 -//#define BT_ADDITIONAL_DEBUG +#ifdef BT_DEBUG +# define BT_ADDITIONAL_DEBUG +#endif //It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms. @@ -690,8 +692,10 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& { #if BT_THREADSAFE int solverBodyId = -1; - bool isRigidBodyType = btRigidBody::upcast(&body) != NULL; - if (isRigidBodyType && !body.isStaticOrKinematicObject()) + const bool isRigidBodyType = btRigidBody::upcast(&body) != NULL; + const bool isStaticOrKinematic = body.isStaticOrKinematicObject(); + const bool isKinematic = body.isKinematicObject(); + if (isRigidBodyType && !isStaticOrKinematic) { // dynamic body // Dynamic bodies can only be in one island, so it's safe to write to the companionId @@ -704,7 +708,7 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body.setCompanionId(solverBodyId); } } - else if (isRigidBodyType && body.isKinematicObject()) + else if (isRigidBodyType && isKinematic) { // // NOTE: must test for kinematic before static because some kinematic objects also diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index a3c9f42eb9..fb15ae31eb 100644 --- a/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -800,6 +800,14 @@ public: ///don't do CCD when the collision filters are not matching if (!ClosestConvexResultCallback::needsCollision(proxy0)) return false; + if (m_pairCache->getOverlapFilterCallback()) { + btBroadphaseProxy* proxy1 = m_me->getBroadphaseHandle(); + bool collides = m_pairCache->needsBroadphaseCollision(proxy0, proxy1); + if (!collides) + { + return false; + } + } btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject; diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp index 9e8705b001..27fdead761 100644 --- a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp @@ -136,8 +136,13 @@ void btRigidBody::setGravity(const btVector3& acceleration) void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) { - m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); - m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); +#ifdef BT_USE_OLD_DAMPING_METHOD + m_linearDamping = btMax(lin_damping, btScalar(0.0)); + m_angularDamping = btMax(ang_damping, btScalar(0.0)); +#else + m_linearDamping = btClamped(lin_damping, btScalar(0.0), btScalar(1.0)); + m_angularDamping = btClamped(ang_damping, btScalar(0.0), btScalar(1.0)); +#endif } ///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping @@ -146,10 +151,9 @@ void btRigidBody::applyDamping(btScalar timeStep) //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74 //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway -//#define USE_OLD_DAMPING_METHOD 1 -#ifdef USE_OLD_DAMPING_METHOD - m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); - m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); +#ifdef BT_USE_OLD_DAMPING_METHOD + m_linearVelocity *= btMax((btScalar(1.0) - timeStep * m_linearDamping), btScalar(0.0)); + m_angularVelocity *= btMax((btScalar(1.0) - timeStep * m_angularDamping), btScalar(0.0)); #else m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep); m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep); @@ -380,6 +384,9 @@ void btRigidBody::integrateVelocities(btScalar step) { m_angularVelocity *= (MAX_ANGVEL / step) / angvel; } + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_angularVelocity); + #endif } btQuaternion btRigidBody::getOrientation() const diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h index 39d47cbbda..943d724cce 100644 --- a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h +++ b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h @@ -305,6 +305,9 @@ public: void applyTorque(const btVector3& torque) { m_totalTorque += torque * m_angularFactor; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_totalTorque); + #endif } void applyForce(const btVector3& force, const btVector3& rel_pos) @@ -316,11 +319,17 @@ public: void applyCentralImpulse(const btVector3& impulse) { m_linearVelocity += impulse * m_linearFactor * m_inverseMass; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_linearVelocity); + #endif } void applyTorqueImpulse(const btVector3& torque) { m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_angularVelocity); + #endif } void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) @@ -361,20 +370,46 @@ public: { m_pushVelocity = v; } - + + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + void clampVelocity(btVector3& v) const { + v.setX( + fmax(-BT_CLAMP_VELOCITY_TO, + fmin(BT_CLAMP_VELOCITY_TO, v.getX())) + ); + v.setY( + fmax(-BT_CLAMP_VELOCITY_TO, + fmin(BT_CLAMP_VELOCITY_TO, v.getY())) + ); + v.setZ( + fmax(-BT_CLAMP_VELOCITY_TO, + fmin(BT_CLAMP_VELOCITY_TO, v.getZ())) + ); + } + #endif + void setTurnVelocity(const btVector3& v) { m_turnVelocity = v; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_turnVelocity); + #endif } void applyCentralPushImpulse(const btVector3& impulse) { m_pushVelocity += impulse * m_linearFactor * m_inverseMass; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_pushVelocity); + #endif } void applyTorqueTurnImpulse(const btVector3& torque) { m_turnVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_turnVelocity); + #endif } void clearForces() @@ -408,12 +443,18 @@ public: { m_updateRevision++; m_linearVelocity = lin_vel; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_linearVelocity); + #endif } inline void setAngularVelocity(const btVector3& ang_vel) { m_updateRevision++; m_angularVelocity = ang_vel; + #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0 + clampVelocity(m_angularVelocity); + #endif } btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp index 5353fe009e..772b774202 100644 --- a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp +++ b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp @@ -171,6 +171,8 @@ void btSimulationIslandManagerMt::initIslandPools() btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland(int id) { + btAssert(id >= 0); + btAssert(id < m_lookupIslandFromId.size()); Island* island = m_lookupIslandFromId[id]; if (island == NULL) { diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp index bdaa473476..a1d5bb9ca8 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp @@ -583,52 +583,6 @@ void btMultiBody::compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const } } -btScalar btMultiBody::getKineticEnergy() const -{ - int num_links = getNumLinks(); - // TODO: would be better not to allocate memory here - btAlignedObjectArray<btVector3> omega; - omega.resize(num_links + 1); - btAlignedObjectArray<btVector3> vel; - vel.resize(num_links + 1); - compTreeLinkVelocities(&omega[0], &vel[0]); - - // we will do the factor of 0.5 at the end - btScalar result = m_baseMass * vel[0].dot(vel[0]); - result += omega[0].dot(m_baseInertia * omega[0]); - - for (int i = 0; i < num_links; ++i) - { - result += m_links[i].m_mass * vel[i + 1].dot(vel[i + 1]); - result += omega[i + 1].dot(m_links[i].m_inertiaLocal * omega[i + 1]); - } - - return 0.5f * result; -} - -btVector3 btMultiBody::getAngularMomentum() const -{ - int num_links = getNumLinks(); - // TODO: would be better not to allocate memory here - btAlignedObjectArray<btVector3> omega; - omega.resize(num_links + 1); - btAlignedObjectArray<btVector3> vel; - vel.resize(num_links + 1); - btAlignedObjectArray<btQuaternion> rot_from_world; - rot_from_world.resize(num_links + 1); - compTreeLinkVelocities(&omega[0], &vel[0]); - - rot_from_world[0] = m_baseQuat; - btVector3 result = quatRotate(rot_from_world[0].inverse(), (m_baseInertia * omega[0])); - - for (int i = 0; i < num_links; ++i) - { - rot_from_world[i + 1] = m_links[i].m_cachedRotParentToThis * rot_from_world[m_links[i].m_parent + 1]; - result += (quatRotate(rot_from_world[i + 1].inverse(), (m_links[i].m_inertiaLocal * omega[i + 1]))); - } - - return result; -} void btMultiBody::clearConstraintForces() { diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h index afed669a7b..be795633fd 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h @@ -307,13 +307,6 @@ public: // btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const; - // - // calculate kinetic energy and angular momentum - // useful for debugging. - // - - btScalar getKineticEnergy() const; - btVector3 getAngularMomentum() const; // // set external forces and torques. Note all external forces/torques are given in the WORLD frame. diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp index ffae5300f0..2788367431 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp @@ -30,23 +30,28 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl btScalar leastSquaredResidual = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); //solve featherstone non-contact constraints - + btScalar nonContactResidual = 0; //printf("m_multiBodyNonContactConstraints = %d\n",m_multiBodyNonContactConstraints.size()); - - for (int j = 0; j < m_multiBodyNonContactConstraints.size(); j++) + for (int i = 0; i < infoGlobal.m_numNonContactInnerIterations; ++i) { - int index = iteration & 1 ? j : m_multiBodyNonContactConstraints.size() - 1 - j; + // reset the nonContactResdual to 0 at start of each inner iteration + nonContactResidual = 0; + for (int j = 0; j < m_multiBodyNonContactConstraints.size(); j++) + { + int index = iteration & 1 ? j : m_multiBodyNonContactConstraints.size() - 1 - j; - btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[index]; + btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[index]; - btScalar residual = resolveSingleConstraintRowGeneric(constraint); - leastSquaredResidual = btMax(leastSquaredResidual, residual * residual); + btScalar residual = resolveSingleConstraintRowGeneric(constraint); + nonContactResidual = btMax(nonContactResidual, residual * residual); - if (constraint.m_multiBodyA) - constraint.m_multiBodyA->setPosUpdated(false); - if (constraint.m_multiBodyB) - constraint.m_multiBodyB->setPosUpdated(false); + if (constraint.m_multiBodyA) + constraint.m_multiBodyA->setPosUpdated(false); + if (constraint.m_multiBodyB) + constraint.m_multiBodyB->setPosUpdated(false); + } } + leastSquaredResidual = btMax(leastSquaredResidual, nonContactResidual); //solve featherstone normal contact for (int j0 = 0; j0 < m_multiBodyNormalContactConstraints.size(); j0++) @@ -1250,7 +1255,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* { const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0()); const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); - + btMultiBody* mbA = fcA ? fcA->m_multiBody : 0; btMultiBody* mbB = fcB ? fcB->m_multiBody : 0; @@ -1270,7 +1275,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* // return; //only a single rollingFriction per manifold - int rollingFriction = 1; + int rollingFriction = 4; for (int j = 0; j < manifold->getNumContacts(); j++) { diff --git a/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h b/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h new file mode 100644 index 0000000000..7b211c4172 --- /dev/null +++ b/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h @@ -0,0 +1,188 @@ +/* + Written by Xuchen Han <xuchenhan2015@u.northwestern.edu> + + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2019 Google Inc. http://bulletphysics.org + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it freely, + subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef BT_CONJUGATE_RESIDUAL_H +#define BT_CONJUGATE_RESIDUAL_H +#include <iostream> +#include <cmath> +#include <limits> +#include <LinearMath/btAlignedObjectArray.h> +#include <LinearMath/btVector3.h> +#include <LinearMath/btScalar.h> +#include "LinearMath/btQuickprof.h" +template <class MatrixX> +class btConjugateResidual +{ + typedef btAlignedObjectArray<btVector3> TVStack; + TVStack r,p,z,temp_p, temp_r, best_x; + // temp_r = A*r + // temp_p = A*p + // z = M^(-1) * temp_p = M^(-1) * A * p + int max_iterations; + btScalar tolerance_squared, best_r; +public: + btConjugateResidual(const int max_it_in) + : max_iterations(max_it_in) + { + tolerance_squared = 1e-2; + } + + virtual ~btConjugateResidual(){} + + // return the number of iterations taken + int solve(MatrixX& A, TVStack& x, const TVStack& b, bool verbose = false) + { + BT_PROFILE("CRSolve"); + btAssert(x.size() == b.size()); + reinitialize(b); + // r = b - A * x --with assigned dof zeroed out + A.multiply(x, temp_r); // borrow temp_r here to store A*x + r = sub(b, temp_r); + // z = M^(-1) * r + A.precondition(r, z); // borrow z to store preconditioned r + r = z; + btScalar residual_norm = norm(r); + if (residual_norm <= tolerance_squared) { + if (verbose) + { + std::cout << "Iteration = 0" << std::endl; + std::cout << "Two norm of the residual = " << residual_norm << std::endl; + } + return 0; + } + p = r; + btScalar r_dot_Ar, r_dot_Ar_new; + // temp_p = A*p + A.multiply(p, temp_p); + // temp_r = A*r + temp_r = temp_p; + r_dot_Ar = dot(r, temp_r); + for (int k = 1; k <= max_iterations; k++) { + // z = M^(-1) * Ap + A.precondition(temp_p, z); + // alpha = r^T * A * r / (Ap)^T * M^-1 * Ap) + btScalar alpha = r_dot_Ar / dot(temp_p, z); + // x += alpha * p; + multAndAddTo(alpha, p, x); + // r -= alpha * z; + multAndAddTo(-alpha, z, r); + btScalar norm_r = norm(r); + if (norm_r < best_r) + { + best_x = x; + best_r = norm_r; + if (norm_r < tolerance_squared) { + if (verbose) + { + std::cout << "ConjugateResidual iterations " << k << std::endl; + } + return k; + } + else + { + if (verbose) + { + std::cout << "ConjugateResidual iterations " << k << " has residual "<< norm_r << std::endl; + } + } + } + // temp_r = A * r; + A.multiply(r, temp_r); + r_dot_Ar_new = dot(r, temp_r); + btScalar beta = r_dot_Ar_new/r_dot_Ar; + r_dot_Ar = r_dot_Ar_new; + // p = beta*p + r; + p = multAndAdd(beta, p, r); + // temp_p = beta*temp_p + temp_r; + temp_p = multAndAdd(beta, temp_p, temp_r); + } + if (verbose) + { + std::cout << "ConjugateResidual max iterations reached " << max_iterations << std::endl; + } + x = best_x; + return max_iterations; + } + + void reinitialize(const TVStack& b) + { + r.resize(b.size()); + p.resize(b.size()); + z.resize(b.size()); + temp_p.resize(b.size()); + temp_r.resize(b.size()); + best_x.resize(b.size()); + best_r = SIMD_INFINITY; + } + + TVStack sub(const TVStack& a, const TVStack& b) + { + // c = a-b + btAssert(a.size() == b.size()); + TVStack c; + c.resize(a.size()); + for (int i = 0; i < a.size(); ++i) + { + c[i] = a[i] - b[i]; + } + return c; + } + + btScalar squaredNorm(const TVStack& a) + { + return dot(a,a); + } + + btScalar norm(const TVStack& a) + { + btScalar ret = 0; + for (int i = 0; i < a.size(); ++i) + { + for (int d = 0; d < 3; ++d) + { + ret = btMax(ret, btFabs(a[i][d])); + } + } + return ret; + } + + btScalar dot(const TVStack& a, const TVStack& b) + { + btScalar ans(0); + for (int i = 0; i < a.size(); ++i) + ans += a[i].dot(b[i]); + return ans; + } + + void multAndAddTo(btScalar s, const TVStack& a, TVStack& result) + { + // result += s*a + btAssert(a.size() == result.size()); + for (int i = 0; i < a.size(); ++i) + result[i] += s * a[i]; + } + + TVStack multAndAdd(btScalar s, const TVStack& a, const TVStack& b) + { + // result = a*s + b + TVStack result; + result.resize(a.size()); + for (int i = 0; i < a.size(); ++i) + result[i] = s * a[i] + b[i]; + return result; + } +}; +#endif /* btConjugateResidual_h */ + diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 1b247641aa..5381ee6265 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -23,12 +23,15 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAligned , m_backupVelocity(backup_v) , m_implicit(false) { - m_preconditioner = new MassPreconditioner(m_softBodies); + m_massPreconditioner = new MassPreconditioner(m_softBodies); + m_KKTPreconditioner = new KKTPreconditioner(m_softBodies, m_projection, m_lf, m_dt, m_implicit); + m_preconditioner = m_KKTPreconditioner; } btDeformableBackwardEulerObjective::~btDeformableBackwardEulerObjective() { - delete m_preconditioner; + delete m_KKTPreconditioner; + delete m_massPreconditioner; } void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar dt) @@ -47,7 +50,7 @@ void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar m_lf[i]->reinitialize(nodeUpdated); } m_projection.reinitialize(nodeUpdated); - m_preconditioner->reinitialize(nodeUpdated); +// m_preconditioner->reinitialize(nodeUpdated); } void btDeformableBackwardEulerObjective::setDt(btScalar dt) @@ -80,6 +83,33 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b); } } + int offset = m_nodes.size(); + for (int i = offset; i < b.size(); ++i) + { + b[i].setZero(); + } + // add in the lagrange multiplier terms + + for (int c = 0; c < m_projection.m_lagrangeMultipliers.size(); ++c) + { + // C^T * lambda + const LagrangeMultiplier& lm = m_projection.m_lagrangeMultipliers[c]; + for (int i = 0; i < lm.m_num_nodes; ++i) + { + for (int j = 0; j < lm.m_num_constraints; ++j) + { + b[lm.m_indices[i]] += x[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j]; + } + } + // C * x + for (int d = 0; d < lm.m_num_constraints; ++d) + { + for (int i = 0; i < lm.m_num_nodes; ++i) + { + b[offset+c][d] += lm.m_weights[i] * x[lm.m_indices[i]].dot(lm.m_dirs[d]); + } + } + } } void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv) @@ -134,7 +164,7 @@ void btDeformableBackwardEulerObjective::computeResidual(btScalar dt, TVStack &r m_lf[i]->addScaledDampingForce(dt, residual); } } - m_projection.project(residual); +// m_projection.project(residual); } btScalar btDeformableBackwardEulerObjective::computeNorm(const TVStack& residual) const @@ -186,9 +216,9 @@ void btDeformableBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack } //set constraints as projections -void btDeformableBackwardEulerObjective::setConstraints() +void btDeformableBackwardEulerObjective::setConstraints(const btContactSolverInfo& infoGlobal) { - m_projection.setConstraints(); + m_projection.setConstraints(infoGlobal); } void btDeformableBackwardEulerObjective::applyDynamicFriction(TVStack& r) diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h index 05ab42ff0a..86579e71ac 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -15,11 +15,12 @@ #ifndef BT_BACKWARD_EULER_OBJECTIVE_H #define BT_BACKWARD_EULER_OBJECTIVE_H -#include "btConjugateGradient.h" +//#include "btConjugateGradient.h" #include "btDeformableLagrangianForce.h" #include "btDeformableMassSpringForce.h" #include "btDeformableGravityForce.h" #include "btDeformableCorotatedForce.h" +#include "btDeformableMousePickingForce.h" #include "btDeformableLinearElasticityForce.h" #include "btDeformableNeoHookeanForce.h" #include "btDeformableContactProjection.h" @@ -39,6 +40,8 @@ public: const TVStack& m_backupVelocity; btAlignedObjectArray<btSoftBody::Node* > m_nodes; bool m_implicit; + MassPreconditioner* m_massPreconditioner; + KKTPreconditioner* m_KKTPreconditioner; btDeformableBackwardEulerObjective(btAlignedObjectArray<btSoftBody *>& softBodies, const TVStack& backup_v); @@ -79,7 +82,7 @@ public: void updateVelocity(const TVStack& dv); //set constraints as projections - void setConstraints(); + void setConstraints(const btContactSolverInfo& infoGlobal); // update the projections and project the residual void project(TVStack& r) @@ -129,6 +132,42 @@ public: // Calculate the total potential energy in the system btScalar totalEnergy(btScalar dt); + + void addLagrangeMultiplier(const TVStack& vec, TVStack& extended_vec) + { + extended_vec.resize(vec.size() + m_projection.m_lagrangeMultipliers.size()); + for (int i = 0; i < vec.size(); ++i) + { + extended_vec[i] = vec[i]; + } + int offset = vec.size(); + for (int i = 0; i < m_projection.m_lagrangeMultipliers.size(); ++i) + { + extended_vec[offset + i].setZero(); + } + } + + void addLagrangeMultiplierRHS(const TVStack& residual, const TVStack& m_dv, TVStack& extended_residual) + { + extended_residual.resize(residual.size() + m_projection.m_lagrangeMultipliers.size()); + for (int i = 0; i < residual.size(); ++i) + { + extended_residual[i] = residual[i]; + } + int offset = residual.size(); + for (int i = 0; i < m_projection.m_lagrangeMultipliers.size(); ++i) + { + const LagrangeMultiplier& lm = m_projection.m_lagrangeMultipliers[i]; + extended_residual[offset + i].setZero(); + for (int d = 0; d < lm.m_num_constraints; ++d) + { + for (int n = 0; n < lm.m_num_nodes; ++n) + { + extended_residual[offset + i][d] += lm.m_weights[n] * m_dv[lm.m_indices[n]].dot(lm.m_dirs[d]); + } + } + } + } }; #endif /* btBackwardEulerObjective_h */ diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp index 7724a8ec69..132699c54f 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp @@ -18,13 +18,15 @@ #include "btDeformableBodySolver.h" #include "btSoftBodyInternals.h" #include "LinearMath/btQuickprof.h" -static const int kMaxConjugateGradientIterations = 50; +static const int kMaxConjugateGradientIterations = 50; btDeformableBodySolver::btDeformableBodySolver() : m_numNodes(0) , m_cg(kMaxConjugateGradientIterations) +, m_cr(kMaxConjugateGradientIterations) , m_maxNewtonIterations(5) , m_newtonTolerance(1e-4) , m_lineSearch(false) +, m_useProjection(false) { m_objective = new btDeformableBackwardEulerObjective(m_softBodies, m_backupVelocity); } @@ -41,7 +43,22 @@ void btDeformableBodySolver::solveDeformableConstraints(btScalar solverdt) { m_objective->computeResidual(solverdt, m_residual); m_objective->applyDynamicFriction(m_residual); - computeStep(m_dv, m_residual); + if (m_useProjection) + { + computeStep(m_dv, m_residual); + } + else + { + TVStack rhs, x; + m_objective->addLagrangeMultiplierRHS(m_residual, m_dv, rhs); + m_objective->addLagrangeMultiplier(m_dv, x); + m_objective->m_preconditioner->reinitialize(true); + computeStep(x, rhs); + for (int i = 0; i<m_dv.size(); ++i) + { + m_dv[i] = x[i]; + } + } updateVelocity(); } else @@ -63,7 +80,7 @@ void btDeformableBodySolver::solveDeformableConstraints(btScalar solverdt) ++counter; } } - + m_objective->computeResidual(solverdt, m_residual); if (m_objective->computeNorm(m_residual) < m_newtonTolerance && i > 0) { @@ -200,7 +217,10 @@ void btDeformableBodySolver::updateDv(btScalar scale) void btDeformableBodySolver::computeStep(TVStack& ddv, const TVStack& residual) { - m_cg.solve(*m_objective, ddv, residual); + if (m_useProjection) + m_cg.solve(*m_objective, ddv, residual, false); + else + m_cr.solve(*m_objective, ddv, residual, false); } void btDeformableBodySolver::reinitialize(const btAlignedObjectArray<btSoftBody *>& softBodies, btScalar dt) @@ -226,27 +246,22 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArray<btSoftBody m_dt = dt; m_objective->reinitialize(nodeUpdated, dt); + updateSoftBodies(); } -void btDeformableBodySolver::setConstraints() +void btDeformableBodySolver::setConstraints(const btContactSolverInfo& infoGlobal) { BT_PROFILE("setConstraint"); - m_objective->setConstraints(); + m_objective->setConstraints(infoGlobal); } -btScalar btDeformableBodySolver::solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies) +btScalar btDeformableBodySolver::solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal) { BT_PROFILE("solveContactConstraints"); - btScalar maxSquaredResidual = m_objective->m_projection.update(deformableBodies,numDeformableBodies); + btScalar maxSquaredResidual = m_objective->m_projection.update(deformableBodies,numDeformableBodies, infoGlobal); return maxSquaredResidual; } -btScalar btDeformableBodySolver::solveSplitImpulse(const btContactSolverInfo& infoGlobal) -{ - BT_PROFILE("solveSplitImpulse"); - return m_objective->m_projection.solveSplitImpulse(infoGlobal); -} - void btDeformableBodySolver::splitImpulseSetup(const btContactSolverInfo& infoGlobal) { m_objective->m_projection.splitImpulseSetup(infoGlobal); @@ -333,8 +348,10 @@ void btDeformableBodySolver::setupDeformableSolve(bool implicit) m_backupVelocity[counter] = psb->m_nodes[j].m_vn; } else + { m_dv[counter] = psb->m_nodes[j].m_v - m_backupVelocity[counter]; - psb->m_nodes[j].m_v = m_backupVelocity[counter] + psb->m_nodes[j].m_vsplit; + } + psb->m_nodes[j].m_v = m_backupVelocity[counter]; ++counter; } } @@ -385,6 +402,7 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt) void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar dt) { + BT_PROFILE("btDeformableBodySolver::predictDeformableMotion"); int i, ni; /* Update */ @@ -423,40 +441,22 @@ void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar d n.m_v *= max_v; } n.m_q = n.m_x + n.m_v * dt; + n.m_penetration = 0; } /* Nodes */ - ATTRIBUTE_ALIGNED16(btDbvtVolume) - vol; - for (i = 0, ni = psb->m_nodes.size(); i < ni; ++i) - { - btSoftBody::Node& n = psb->m_nodes[i]; - btVector3 points[2] = {n.m_x, n.m_q}; - vol = btDbvtVolume::FromPoints(points, 2); - vol.Expand(btVector3(psb->m_sst.radmrg, psb->m_sst.radmrg, psb->m_sst.radmrg)); - psb->m_ndbvt.update(n.m_leaf, vol); - } - + psb->updateNodeTree(true, true); if (!psb->m_fdbvt.empty()) { - for (int i = 0; i < psb->m_faces.size(); ++i) - { - btSoftBody::Face& f = psb->m_faces[i]; - btVector3 points[6] = {f.m_n[0]->m_x, f.m_n[0]->m_q, - f.m_n[1]->m_x, f.m_n[1]->m_q, - f.m_n[2]->m_x, f.m_n[2]->m_q}; - vol = btDbvtVolume::FromPoints(points, 6); - vol.Expand(btVector3(psb->m_sst.radmrg, psb->m_sst.radmrg, psb->m_sst.radmrg)); - psb->m_fdbvt.update(f.m_leaf, vol); - } + psb->updateFaceTree(true, true); } - /* Clear contacts */ + /* Clear contacts */ psb->m_nodeRigidContacts.resize(0); psb->m_faceRigidContacts.resize(0); psb->m_faceNodeContacts.resize(0); /* Optimize dbvt's */ - psb->m_ndbvt.optimizeIncremental(1); - psb->m_fdbvt.optimizeIncremental(1); +// psb->m_ndbvt.optimizeIncremental(1); +// psb->m_fdbvt.optimizeIncremental(1); } diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h index f78a8f696b..d4e5f4c603 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h @@ -22,7 +22,8 @@ #include "btDeformableMultiBodyDynamicsWorld.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" - +#include "btConjugateResidual.h" +#include "btConjugateGradient.h" struct btCollisionObjectWrapper; class btDeformableBackwardEulerObjective; class btDeformableMultiBodyDynamicsWorld; @@ -40,14 +41,15 @@ protected: TVStack m_backupVelocity; // backed up v, equals v_n for implicit, equals v_{n+1}^* for explicit btScalar m_dt; // dt btConjugateGradient<btDeformableBackwardEulerObjective> m_cg; // CG solver + btConjugateResidual<btDeformableBackwardEulerObjective> m_cr; // CR solver bool m_implicit; // use implicit scheme if true, explicit scheme if false int m_maxNewtonIterations; // max number of newton iterations btScalar m_newtonTolerance; // stop newton iterations if f(x) < m_newtonTolerance bool m_lineSearch; // If true, use newton's method with line search under implicit scheme - public: // handles data related to objective function btDeformableBackwardEulerObjective* m_objective; + bool m_useProjection; btDeformableBodySolver(); @@ -61,15 +63,11 @@ public: // update soft body normals virtual void updateSoftBodies(); + virtual btScalar solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal); + // solve the momentum equation virtual void solveDeformableConstraints(btScalar solverdt); - // solve the contact between deformable and rigid as well as among deformables - btScalar solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies); - - // solve the position error between deformable and rigid as well as among deformables; - btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal); - // set up the position error in split impulse void splitImpulseSetup(const btContactSolverInfo& infoGlobal); @@ -77,7 +75,7 @@ public: void reinitialize(const btAlignedObjectArray<btSoftBody *>& softBodies, btScalar dt); // set up contact constraints - void setConstraints(); + void setConstraints(const btContactSolverInfo& infoGlobal); // add in elastic forces and gravity to obtain v_{n+1}^* and calls predictDeformableMotion virtual void predictMotion(btScalar solverdt); diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp index e8219dc50e..2864446de6 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp @@ -15,9 +15,9 @@ #include "btDeformableContactConstraint.h" /* ================ Deformable Node Anchor =================== */ -btDeformableNodeAnchorConstraint::btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& a) +btDeformableNodeAnchorConstraint::btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& a, const btContactSolverInfo& infoGlobal) : m_anchor(&a) -, btDeformableContactConstraint(a.m_cti.m_normal) +, btDeformableContactConstraint(a.m_cti.m_normal, infoGlobal) { } @@ -79,14 +79,14 @@ btVector3 btDeformableNodeAnchorConstraint::getVa() const return va; } -btScalar btDeformableNodeAnchorConstraint::solveConstraint() +btScalar btDeformableNodeAnchorConstraint::solveConstraint(const btContactSolverInfo& infoGlobal) { const btSoftBody::sCti& cti = m_anchor->m_cti; btVector3 va = getVa(); btVector3 vb = getVb(); btVector3 vr = (vb - va); // + (m_anchor->m_node->m_x - cti.m_colObj->getWorldTransform() * m_anchor->m_local) * 10.0 - const btScalar dn = btDot(vr, cti.m_normal); + const btScalar dn = btDot(vr, vr); // dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt btScalar residualSquare = dn*dn; btVector3 impulse = m_anchor->m_c0 * vr; @@ -134,14 +134,15 @@ void btDeformableNodeAnchorConstraint::applyImpulse(const btVector3& impulse) } /* ================ Deformable vs. Rigid =================== */ -btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c) +btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c, const btContactSolverInfo& infoGlobal) : m_contact(&c) -, btDeformableContactConstraint(c.m_cti.m_normal) +, btDeformableContactConstraint(c.m_cti.m_normal, infoGlobal) { m_total_normal_dv.setZero(); m_total_tangent_dv.setZero(); - // penetration is non-positive. The magnitude of penetration is the depth of penetration. - m_penetration = btMin(btScalar(0), c.m_cti.m_offset); + // The magnitude of penetration is the depth of penetration. + m_penetration = c.m_cti.m_offset; +// m_penetration = btMin(btScalar(0),c.m_cti.m_offset); } btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btDeformableRigidContactConstraint& other) @@ -206,16 +207,16 @@ btVector3 btDeformableRigidContactConstraint::getVa() const return va; } -btScalar btDeformableRigidContactConstraint::solveConstraint() +btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal) { const btSoftBody::sCti& cti = m_contact->m_cti; btVector3 va = getVa(); btVector3 vb = getVb(); btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); + btScalar dn = btDot(vr, cti.m_normal) + m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep; // dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt btScalar residualSquare = dn*dn; - btVector3 impulse = m_contact->m_c0 * vr; + btVector3 impulse = m_contact->m_c0 * (vr + m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep * cti.m_normal) ; const btVector3 impulse_normal = m_contact->m_c0 * (cti.m_normal * dn); btVector3 impulse_tangent = impulse - impulse_normal; btVector3 old_total_tangent_dv = m_total_tangent_dv; @@ -256,6 +257,8 @@ btScalar btDeformableRigidContactConstraint::solveConstraint() impulse = impulse_normal + impulse_tangent; // apply impulse to deformable nodes involved and change their velocities applyImpulse(impulse); + if (residualSquare < 1e-7) + return residualSquare; // apply impulse to the rigid/multibodies involved and change their velocities if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { @@ -285,43 +288,17 @@ btScalar btDeformableRigidContactConstraint::solveConstraint() } } } +// va = getVa(); +// vb = getVb(); +// vr = vb - va; +// btScalar dn1 = btDot(vr, cti.m_normal) / 150; +// m_penetration += dn1; return residualSquare; } - -btScalar btDeformableRigidContactConstraint::solveSplitImpulse(const btContactSolverInfo& infoGlobal) -{ - const btSoftBody::sCti& cti = m_contact->m_cti; - const btScalar dn = m_penetration; - if (dn != 0) - { - const btVector3 impulse = (m_contact->m_c0 * (cti.m_normal * dn / infoGlobal.m_timeStep)); - // one iteration of the position impulse corrects all the position error at this timestep - m_penetration -= dn; - // apply impulse to deformable nodes involved and change their position - applySplitImpulse(impulse); - // apply impulse to the rigid/multibodies involved and change their position - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - btRigidBody* rigidCol = 0; - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - if (rigidCol) - { - rigidCol->applyPushImpulse(impulse, m_contact->m_c1); - } - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - // todo xuchenhan@ - } - return (m_penetration/infoGlobal.m_timeStep) * (m_penetration/infoGlobal.m_timeStep); - } - return 0; -} - /* ================ Node vs. Rigid =================== */ -btDeformableNodeRigidContactConstraint::btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact) +btDeformableNodeRigidContactConstraint::btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact, const btContactSolverInfo& infoGlobal) : m_node(contact.m_node) - , btDeformableRigidContactConstraint(contact) + , btDeformableRigidContactConstraint(contact, infoGlobal) { } @@ -349,22 +326,17 @@ void btDeformableNodeRigidContactConstraint::applyImpulse(const btVector3& impul contact->m_node->m_v -= dv; } -void btDeformableNodeRigidContactConstraint::applySplitImpulse(const btVector3& impulse) -{ - const btSoftBody::DeformableNodeRigidContact* contact = getContact(); - btVector3 dv = impulse * contact->m_c2; - contact->m_node->m_vsplit -= dv; -}; - /* ================ Face vs. Rigid =================== */ -btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact) +btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact, const btContactSolverInfo& infoGlobal, bool useStrainLimiting) : m_face(contact.m_face) -, btDeformableRigidContactConstraint(contact) +, m_useStrainLimiting(useStrainLimiting) +, btDeformableRigidContactConstraint(contact, infoGlobal) { } btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btDeformableFaceRigidContactConstraint& other) : m_face(other.m_face) +, m_useStrainLimiting(other.m_useStrainLimiting) , btDeformableRigidContactConstraint(other) { } @@ -411,47 +383,70 @@ void btDeformableFaceRigidContactConstraint::applyImpulse(const btVector3& impul v1 -= dv * contact->m_weights[1]; if (im2 > 0) v2 -= dv * contact->m_weights[2]; - - // apply strain limiting to prevent undamped modes - btScalar m01 = (btScalar(1)/(im0 + im1)); - btScalar m02 = (btScalar(1)/(im0 + im2)); - btScalar m12 = (btScalar(1)/(im1 + im2)); - - btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0)); - btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1)); - btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2)); - - v0 += dv0; - v1 += dv1; - v2 += dv2; -} - -void btDeformableFaceRigidContactConstraint::applySplitImpulse(const btVector3& impulse) -{ - const btSoftBody::DeformableFaceRigidContact* contact = getContact(); - btVector3 dv = impulse * contact->m_c2; - btSoftBody::Face* face = contact->m_face; - - btVector3& v0 = face->m_n[0]->m_vsplit; - btVector3& v1 = face->m_n[1]->m_vsplit; - btVector3& v2 = face->m_n[2]->m_vsplit; - const btScalar& im0 = face->m_n[0]->m_im; - const btScalar& im1 = face->m_n[1]->m_im; - const btScalar& im2 = face->m_n[2]->m_im; - if (im0 > 0) - v0 -= dv * contact->m_weights[0]; - if (im1 > 0) - v1 -= dv * contact->m_weights[1]; - if (im2 > 0) - v2 -= dv * contact->m_weights[2]; + if (m_useStrainLimiting) + { + btScalar relaxation = 1./btScalar(m_infoGlobal->m_numIterations); + btScalar m01 = (relaxation/(im0 + im1)); + btScalar m02 = (relaxation/(im0 + im2)); + btScalar m12 = (relaxation/(im1 + im2)); + #ifdef USE_STRAIN_RATE_LIMITING + // apply strain limiting to prevent the new velocity to change the current length of the edge by more than 1%. + btScalar p = 0.01; + btVector3& x0 = face->m_n[0]->m_x; + btVector3& x1 = face->m_n[1]->m_x; + btVector3& x2 = face->m_n[2]->m_x; + const btVector3 x_diff[3] = {x1-x0, x2-x0, x2-x1}; + const btVector3 v_diff[3] = {v1-v0, v2-v0, v2-v1}; + btVector3 u[3]; + btScalar x_diff_dot_u, dn[3]; + btScalar dt = m_infoGlobal->m_timeStep; + for (int i = 0; i < 3; ++i) + { + btScalar x_diff_norm = x_diff[i].safeNorm(); + btScalar x_diff_norm_new = (x_diff[i] + v_diff[i] * dt).safeNorm(); + btScalar strainRate = x_diff_norm_new/x_diff_norm; + u[i] = v_diff[i]; + u[i].safeNormalize(); + if (x_diff_norm == 0 || (1-p <= strainRate && strainRate <= 1+p)) + { + dn[i] = 0; + continue; + } + x_diff_dot_u = btDot(x_diff[i], u[i]); + btScalar s; + if (1-p > strainRate) + { + s = 1/dt * (-x_diff_dot_u - btSqrt(x_diff_dot_u*x_diff_dot_u + (p*p-2*p) * x_diff_norm * x_diff_norm)); + } + else + { + s = 1/dt * (-x_diff_dot_u + btSqrt(x_diff_dot_u*x_diff_dot_u + (p*p+2*p) * x_diff_norm * x_diff_norm)); + } + // x_diff_norm_new = (x_diff[i] + s * u[i] * dt).safeNorm(); + // strainRate = x_diff_norm_new/x_diff_norm; + dn[i] = s - v_diff[i].safeNorm(); + } + btVector3 dv0 = im0 * (m01 * u[0]*(-dn[0]) + m02 * u[1]*-(dn[1])); + btVector3 dv1 = im1 * (m01 * u[0]*(dn[0]) + m12 * u[2]*(-dn[2])); + btVector3 dv2 = im2 * (m12 * u[2]*(dn[2]) + m02 * u[1]*(dn[1])); + #else + // apply strain limiting to prevent undamped modes + btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0)); + btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1)); + btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2)); + #endif + v0 += dv0; + v1 += dv1; + v2 += dv2; + } } /* ================ Face vs. Node =================== */ -btDeformableFaceNodeContactConstraint::btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact) +btDeformableFaceNodeContactConstraint::btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact, const btContactSolverInfo& infoGlobal) : m_node(contact.m_node) , m_face(contact.m_face) , m_contact(&contact) -, btDeformableContactConstraint(contact.m_normal) +, btDeformableContactConstraint(contact.m_normal, infoGlobal) { m_total_normal_dv.setZero(); m_total_tangent_dv.setZero(); @@ -487,7 +482,7 @@ btVector3 btDeformableFaceNodeContactConstraint::getDv(const btSoftBody::Node* n return dv * contact->m_weights[2]; } -btScalar btDeformableFaceNodeContactConstraint::solveConstraint() +btScalar btDeformableFaceNodeContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal) { btVector3 va = getVa(); btVector3 vb = getVb(); @@ -577,15 +572,4 @@ void btDeformableFaceNodeContactConstraint::applyImpulse(const btVector3& impuls { v2 -= dvb * contact->m_weights[2]; } - // todo: Face node constraints needs more work -// btScalar m01 = (btScalar(1)/(im0 + im1)); -// btScalar m02 = (btScalar(1)/(im0 + im2)); -// btScalar m12 = (btScalar(1)/(im1 + im2)); -// -// btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0)); -// btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1)); -// btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2)); -// v0 += dv0; -// v1 += dv1; -// v2 += dv2; } diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h index 912119e7c3..9f9d5bf0a3 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h @@ -24,34 +24,33 @@ public: // True if the friction is static // False if the friction is dynamic bool m_static; - - // normal of the contact - btVector3 m_normal; - - btDeformableContactConstraint(const btVector3& normal): m_static(false), m_normal(normal) - { - } - - btDeformableContactConstraint(bool isStatic, const btVector3& normal): m_static(isStatic), m_normal(normal) - { - } - - btDeformableContactConstraint(const btDeformableContactConstraint& other) - : m_static(other.m_static) - , m_normal(other.m_normal) - { - - } - btDeformableContactConstraint(){} - + const btContactSolverInfo* m_infoGlobal; + + // normal of the contact + btVector3 m_normal; + + btDeformableContactConstraint(const btVector3& normal, const btContactSolverInfo& infoGlobal): m_static(false), m_normal(normal), m_infoGlobal(&infoGlobal) + { + } + + btDeformableContactConstraint(bool isStatic, const btVector3& normal, const btContactSolverInfo& infoGlobal): m_static(isStatic), m_normal(normal), m_infoGlobal(&infoGlobal) + { + } + + btDeformableContactConstraint(){} + + btDeformableContactConstraint(const btDeformableContactConstraint& other) + : m_static(other.m_static) + , m_normal(other.m_normal) + , m_infoGlobal(other.m_infoGlobal) + { + } + virtual ~btDeformableContactConstraint(){} // solve the constraint with inelastic impulse and return the error, which is the square of normal component of velocity diffrerence // the constraint is solved by calculating the impulse between object A and B in the contact and apply the impulse to both objects involved in the contact - virtual btScalar solveConstraint() = 0; - - // solve the position error by applying an inelastic impulse that changes only the position (not velocity) - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal) = 0; + virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal) = 0; // get the velocity of the object A in the contact virtual btVector3 getVa() const = 0; @@ -65,9 +64,6 @@ public: // apply impulse to the soft body node and/or face involved virtual void applyImpulse(const btVector3& impulse) = 0; - // apply position based impulse to the soft body node and/or face involved - virtual void applySplitImpulse(const btVector3& impulse) = 0; - // scale the penetration depth by erp virtual void setPenetrationScale(btScalar scale) = 0; }; @@ -77,29 +73,21 @@ public: class btDeformableStaticConstraint : public btDeformableContactConstraint { public: - const btSoftBody::Node* m_node; - - btDeformableStaticConstraint(){} + btSoftBody::Node* m_node; - btDeformableStaticConstraint(const btSoftBody::Node* node): m_node(node), btDeformableContactConstraint(false, btVector3(0,0,0)) + btDeformableStaticConstraint(btSoftBody::Node* node, const btContactSolverInfo& infoGlobal): m_node(node), btDeformableContactConstraint(false, btVector3(0,0,0), infoGlobal) { } - + btDeformableStaticConstraint(){} btDeformableStaticConstraint(const btDeformableStaticConstraint& other) : m_node(other.m_node) , btDeformableContactConstraint(other) { - } virtual ~btDeformableStaticConstraint(){} - virtual btScalar solveConstraint() - { - return 0; - } - - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal) + virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal) { return 0; } @@ -120,7 +108,6 @@ public: } virtual void applyImpulse(const btVector3& impulse){} - virtual void applySplitImpulse(const btVector3& impulse){} virtual void setPenetrationScale(btScalar scale){} }; @@ -130,19 +117,15 @@ class btDeformableNodeAnchorConstraint : public btDeformableContactConstraint { public: const btSoftBody::DeformableNodeRigidAnchor* m_anchor; - - btDeformableNodeAnchorConstraint(){} - btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& c); + + btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& c, const btContactSolverInfo& infoGlobal); btDeformableNodeAnchorConstraint(const btDeformableNodeAnchorConstraint& other); + btDeformableNodeAnchorConstraint(){} virtual ~btDeformableNodeAnchorConstraint() { } - virtual btScalar solveConstraint(); - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal) - { - // todo xuchenhan@ - return 0; - } + virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal); + // object A is the rigid/multi body, and object B is the deformable node/face virtual btVector3 getVa() const; // get the velocity of the deformable node in contact @@ -152,10 +135,7 @@ public: return btVector3(0,0,0); } virtual void applyImpulse(const btVector3& impulse); - virtual void applySplitImpulse(const btVector3& impulse) - { - // todo xuchenhan@ - }; + virtual void setPenetrationScale(btScalar scale){} }; @@ -169,10 +149,10 @@ public: btVector3 m_total_tangent_dv; btScalar m_penetration; const btSoftBody::DeformableRigidContact* m_contact; - - btDeformableRigidContactConstraint(){} - btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c); + + btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c, const btContactSolverInfo& infoGlobal); btDeformableRigidContactConstraint(const btDeformableRigidContactConstraint& other); + btDeformableRigidContactConstraint(){} virtual ~btDeformableRigidContactConstraint() { } @@ -180,9 +160,7 @@ public: // object A is the rigid/multi body, and object B is the deformable node/face virtual btVector3 getVa() const; - virtual btScalar solveConstraint(); - - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal); + virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal); virtual void setPenetrationScale(btScalar scale) { @@ -196,12 +174,11 @@ class btDeformableNodeRigidContactConstraint : public btDeformableRigidContactCo { public: // the deformable node in contact - const btSoftBody::Node* m_node; - - btDeformableNodeRigidContactConstraint(){} - btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact); + btSoftBody::Node* m_node; + + btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact, const btContactSolverInfo& infoGlobal); btDeformableNodeRigidContactConstraint(const btDeformableNodeRigidContactConstraint& other); - + btDeformableNodeRigidContactConstraint(){} virtual ~btDeformableNodeRigidContactConstraint() { } @@ -219,7 +196,6 @@ public: } virtual void applyImpulse(const btVector3& impulse); - virtual void applySplitImpulse(const btVector3& impulse); }; // @@ -228,10 +204,10 @@ class btDeformableFaceRigidContactConstraint : public btDeformableRigidContactCo { public: const btSoftBody::Face* m_face; - btDeformableFaceRigidContactConstraint(){} - btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact); + bool m_useStrainLimiting; + btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact, const btContactSolverInfo& infoGlobal, bool useStrainLimiting); btDeformableFaceRigidContactConstraint(const btDeformableFaceRigidContactConstraint& other); - + btDeformableFaceRigidContactConstraint(): m_useStrainLimiting(false) {} virtual ~btDeformableFaceRigidContactConstraint() { } @@ -249,7 +225,6 @@ public: } virtual void applyImpulse(const btVector3& impulse); - virtual void applySplitImpulse(const btVector3& impulse); }; // @@ -263,19 +238,11 @@ public: btVector3 m_total_normal_dv; btVector3 m_total_tangent_dv; - btDeformableFaceNodeContactConstraint(){} - - btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact); - + btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact, const btContactSolverInfo& infoGlobal); + btDeformableFaceNodeContactConstraint(){} virtual ~btDeformableFaceNodeContactConstraint(){} - virtual btScalar solveConstraint(); - - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal) - { - // todo: xuchenhan@ - return 0; - } + virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal); // get the velocity of the object A in the contact virtual btVector3 getVa() const; @@ -293,10 +260,7 @@ public: } virtual void applyImpulse(const btVector3& impulse); - virtual void applySplitImpulse(const btVector3& impulse) - { - // todo xuchenhan@ - } + virtual void setPenetrationScale(btScalar scale){} }; #endif /* BT_DEFORMABLE_CONTACT_CONSTRAINT_H */ diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp index 5a4f3241b4..22ca8bf582 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp @@ -17,7 +17,7 @@ #include "btDeformableMultiBodyDynamicsWorld.h" #include <algorithm> #include <cmath> -btScalar btDeformableContactProjection::update(btCollisionObject** deformableBodies,int numDeformableBodies) +btScalar btDeformableContactProjection::update(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal) { btScalar residualSquare = 0; for (int i = 0; i < numDeformableBodies; ++i) @@ -32,25 +32,25 @@ btScalar btDeformableContactProjection::update(btCollisionObject** deformableBod for (int k = 0; k < m_nodeRigidConstraints[j].size(); ++k) { btDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[j][k]; - btScalar localResidualSquare = constraint.solveConstraint(); + btScalar localResidualSquare = constraint.solveConstraint(infoGlobal); residualSquare = btMax(residualSquare, localResidualSquare); } for (int k = 0; k < m_nodeAnchorConstraints[j].size(); ++k) { btDeformableNodeAnchorConstraint& constraint = m_nodeAnchorConstraints[j][k]; - btScalar localResidualSquare = constraint.solveConstraint(); + btScalar localResidualSquare = constraint.solveConstraint(infoGlobal); residualSquare = btMax(residualSquare, localResidualSquare); } for (int k = 0; k < m_faceRigidConstraints[j].size(); ++k) { btDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[j][k]; - btScalar localResidualSquare = constraint.solveConstraint(); + btScalar localResidualSquare = constraint.solveConstraint(infoGlobal); residualSquare = btMax(residualSquare, localResidualSquare); } for (int k = 0; k < m_deformableConstraints[j].size(); ++k) { btDeformableFaceNodeContactConstraint& constraint = m_deformableConstraints[j][k]; - btScalar localResidualSquare = constraint.solveConstraint(); + btScalar localResidualSquare = constraint.solveConstraint(infoGlobal); residualSquare = btMax(residualSquare, localResidualSquare); } } @@ -77,39 +77,8 @@ void btDeformableContactProjection::splitImpulseSetup(const btContactSolverInfo& } } -btScalar btDeformableContactProjection::solveSplitImpulse(const btContactSolverInfo& infoGlobal) -{ - btScalar residualSquare = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - // node constraints - for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j) - { - btDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[i][j]; - btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal); - residualSquare = btMax(residualSquare, localResidualSquare); - } - // anchor constraints - for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j) - { - btDeformableNodeAnchorConstraint& constraint = m_nodeAnchorConstraints[i][j]; - btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal); - residualSquare = btMax(residualSquare, localResidualSquare); - } - // face constraints - for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j) - { - btDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[i][j]; - btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal); - residualSquare = btMax(residualSquare, localResidualSquare); - } - - } - return residualSquare; -} - -void btDeformableContactProjection::setConstraints() -{ +void btDeformableContactProjection::setConstraints(const btContactSolverInfo& infoGlobal) +{ BT_PROFILE("setConstraints"); for (int i = 0; i < m_softBodies.size(); ++i) { @@ -124,7 +93,7 @@ void btDeformableContactProjection::setConstraints() { if (psb->m_nodes[j].m_im == 0) { - btDeformableStaticConstraint static_constraint(&psb->m_nodes[j]); + btDeformableStaticConstraint static_constraint(&psb->m_nodes[j], infoGlobal); m_staticConstraints[i].push_back(static_constraint); } } @@ -139,7 +108,7 @@ void btDeformableContactProjection::setConstraints() continue; } anchor.m_c1 = anchor.m_cti.m_colObj->getWorldTransform().getBasis() * anchor.m_local; - btDeformableNodeAnchorConstraint constraint(anchor); + btDeformableNodeAnchorConstraint constraint(anchor, infoGlobal); m_nodeAnchorConstraints[i].push_back(constraint); } @@ -152,7 +121,7 @@ void btDeformableContactProjection::setConstraints() { continue; } - btDeformableNodeRigidContactConstraint constraint(contact); + btDeformableNodeRigidContactConstraint constraint(contact, infoGlobal); btVector3 va = constraint.getVa(); btVector3 vb = constraint.getVb(); const btVector3 vr = vb - va; @@ -173,7 +142,7 @@ void btDeformableContactProjection::setConstraints() { continue; } - btDeformableFaceRigidContactConstraint constraint(contact); + btDeformableFaceRigidContactConstraint constraint(contact, infoGlobal, m_useStrainLimiting); btVector3 va = constraint.getVa(); btVector3 vb = constraint.getVb(); const btVector3 vr = vb - va; @@ -184,253 +153,404 @@ void btDeformableContactProjection::setConstraints() m_faceRigidConstraints[i].push_back(constraint); } } - - // set Deformable Face vs. Deformable Node constraint - for (int j = 0; j < psb->m_faceNodeContacts.size(); ++j) - { - const btSoftBody::DeformableFaceNodeContact& contact = psb->m_faceNodeContacts[j]; - - btDeformableFaceNodeContactConstraint constraint(contact); - btVector3 va = constraint.getVa(); - btVector3 vb = constraint.getVb(); - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, contact.m_normal); - if (dn > -SIMD_EPSILON) - { - m_deformableConstraints[i].push_back(constraint); - } - } } } void btDeformableContactProjection::project(TVStack& x) { - const int dim = 3; - for (int index = 0; index < m_projectionsDict.size(); ++index) - { - btAlignedObjectArray<btVector3>& projectionDirs = *m_projectionsDict.getAtIndex(index); - size_t i = m_projectionsDict.getKeyAtIndex(index).getUid1(); - if (projectionDirs.size() >= dim) - { - // static node - x[i].setZero(); - continue; - } - else if (projectionDirs.size() == 2) - { - btVector3 dir0 = projectionDirs[0]; - btVector3 dir1 = projectionDirs[1]; - btVector3 free_dir = btCross(dir0, dir1); - if (free_dir.safeNorm() < SIMD_EPSILON) - { - x[i] -= x[i].dot(dir0) * dir0; - x[i] -= x[i].dot(dir1) * dir1; - } - else - { - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - } - } - else - { - btAssert(projectionDirs.size() == 1); - btVector3 dir0 = projectionDirs[0]; - x[i] -= x[i].dot(dir0) * dir0; - } - } +#ifndef USE_MGS + const int dim = 3; + for (int index = 0; index < m_projectionsDict.size(); ++index) + { + btAlignedObjectArray<btVector3>& projectionDirs = *m_projectionsDict.getAtIndex(index); + size_t i = m_projectionsDict.getKeyAtIndex(index).getUid1(); + if (projectionDirs.size() >= dim) + { + // static node + x[i].setZero(); + continue; + } + else if (projectionDirs.size() == 2) + { + btVector3 dir0 = projectionDirs[0]; + btVector3 dir1 = projectionDirs[1]; + btVector3 free_dir = btCross(dir0, dir1); + if (free_dir.safeNorm() < SIMD_EPSILON) + { + x[i] -= x[i].dot(dir0) * dir0; + x[i] -= x[i].dot(dir1) * dir1; + } + else + { + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + } + } + else + { + btAssert(projectionDirs.size() == 1); + btVector3 dir0 = projectionDirs[0]; + x[i] -= x[i].dot(dir0) * dir0; + } + } +#else + btReducedVector p(x.size()); + for (int i = 0; i < m_projections.size(); ++i) + { + p += (m_projections[i].dot(x) * m_projections[i]); + } + for (int i = 0; i < p.m_indices.size(); ++i) + { + x[p.m_indices[i]] -= p.m_vecs[i]; + } +#endif } void btDeformableContactProjection::setProjection() { - btAlignedObjectArray<btVector3> units; - units.push_back(btVector3(1,0,0)); - units.push_back(btVector3(0,1,0)); - units.push_back(btVector3(0,0,1)); - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - if (!psb->isActive()) - { - continue; - } - for (int j = 0; j < m_staticConstraints[i].size(); ++j) - { - int index = m_staticConstraints[i][j].m_node->index; - if (m_projectionsDict.find(index) == NULL) +#ifndef USE_MGS + BT_PROFILE("btDeformableContactProjection::setProjection"); + btAlignedObjectArray<btVector3> units; + units.push_back(btVector3(1,0,0)); + units.push_back(btVector3(0,1,0)); + units.push_back(btVector3(0,0,1)); + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (!psb->isActive()) + { + continue; + } + for (int j = 0; j < m_staticConstraints[i].size(); ++j) + { + int index = m_staticConstraints[i][j].m_node->index; + m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY; + if (m_projectionsDict.find(index) == NULL) + { + m_projectionsDict.insert(index, units); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + for (int k = 0; k < 3; ++k) + { + projections.push_back(units[k]); + } + } + } + for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j) + { + int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index; + m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY; + if (m_projectionsDict.find(index) == NULL) + { + m_projectionsDict.insert(index, units); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + for (int k = 0; k < 3; ++k) + { + projections.push_back(units[k]); + } + } + } + for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j) + { + int index = m_nodeRigidConstraints[i][j].m_node->index; + m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset; + if (m_nodeRigidConstraints[i][j].m_static) + { + if (m_projectionsDict.find(index) == NULL) + { + m_projectionsDict.insert(index, units); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + for (int k = 0; k < 3; ++k) + { + projections.push_back(units[k]); + } + } + } + else + { + if (m_projectionsDict.find(index) == NULL) + { + btAlignedObjectArray<btVector3> projections; + projections.push_back(m_nodeRigidConstraints[i][j].m_normal); + m_projectionsDict.insert(index, projections); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + projections.push_back(m_nodeRigidConstraints[i][j].m_normal); + } + } + } + for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j) + { + const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face; + btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset; + for (int k = 0; k < 3; ++k) + { + face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration); + } + for (int k = 0; k < 3; ++k) + { + btSoftBody::Node* node = face->m_n[k]; + node->m_penetration = true; + int index = node->index; + if (m_faceRigidConstraints[i][j].m_static) + { + if (m_projectionsDict.find(index) == NULL) + { + m_projectionsDict.insert(index, units); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + for (int k = 0; k < 3; ++k) + { + projections.push_back(units[k]); + } + } + } + else + { + if (m_projectionsDict.find(index) == NULL) + { + btAlignedObjectArray<btVector3> projections; + projections.push_back(m_faceRigidConstraints[i][j].m_normal); + m_projectionsDict.insert(index, projections); + } + else + { + btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + projections.push_back(m_faceRigidConstraints[i][j].m_normal); + } + } + } + } + } +#else + int dof = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + dof += m_softBodies[i]->m_nodes.size(); + } + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (!psb->isActive()) + { + continue; + } + for (int j = 0; j < m_staticConstraints[i].size(); ++j) + { + int index = m_staticConstraints[i][j].m_node->index; + m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY; + btAlignedObjectArray<int> indices; + btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3; + indices.push_back(index); + vecs1.push_back(btVector3(1,0,0)); + vecs2.push_back(btVector3(0,1,0)); + vecs3.push_back(btVector3(0,0,1)); + m_projections.push_back(btReducedVector(dof, indices, vecs1)); + m_projections.push_back(btReducedVector(dof, indices, vecs2)); + m_projections.push_back(btReducedVector(dof, indices, vecs3)); + } + + for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j) + { + int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index; + m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY; + btAlignedObjectArray<int> indices; + btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3; + indices.push_back(index); + vecs1.push_back(btVector3(1,0,0)); + vecs2.push_back(btVector3(0,1,0)); + vecs3.push_back(btVector3(0,0,1)); + m_projections.push_back(btReducedVector(dof, indices, vecs1)); + m_projections.push_back(btReducedVector(dof, indices, vecs2)); + m_projections.push_back(btReducedVector(dof, indices, vecs3)); + } + for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j) + { + int index = m_nodeRigidConstraints[i][j].m_node->index; + m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset; + btAlignedObjectArray<int> indices; + indices.push_back(index); + btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3; + if (m_nodeRigidConstraints[i][j].m_static) + { + vecs1.push_back(btVector3(1,0,0)); + vecs2.push_back(btVector3(0,1,0)); + vecs3.push_back(btVector3(0,0,1)); + m_projections.push_back(btReducedVector(dof, indices, vecs1)); + m_projections.push_back(btReducedVector(dof, indices, vecs2)); + m_projections.push_back(btReducedVector(dof, indices, vecs3)); + } + else + { + vecs1.push_back(m_nodeRigidConstraints[i][j].m_normal); + m_projections.push_back(btReducedVector(dof, indices, vecs1)); + } + } + for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j) + { + const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face; + btVector3 bary = m_faceRigidConstraints[i][j].getContact()->m_bary; + btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset; + for (int k = 0; k < 3; ++k) + { + face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration); + } + if (m_faceRigidConstraints[i][j].m_static) { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - for (int k = 0; k < 3; ++k) + for (int l = 0; l < 3; ++l) { - projections.push_back(units[k]); - } - } - } - for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j) - { - int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index; - if (m_projectionsDict.find(index) == NULL) - { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - for (int k = 0; k < 3; ++k) - { - projections.push_back(units[k]); - } - } - } - for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j) - { - int index = m_nodeRigidConstraints[i][j].m_node->index; - if (m_nodeRigidConstraints[i][j].m_static) - { - if (m_projectionsDict.find(index) == NULL) - { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; + + btReducedVector rv(dof); for (int k = 0; k < 3; ++k) { - projections.push_back(units[k]); + rv.m_indices.push_back(face->m_n[k]->index); + btVector3 v(0,0,0); + v[l] = bary[k]; + rv.m_vecs.push_back(v); + rv.sort(); } + m_projections.push_back(rv); } } else { - if (m_projectionsDict.find(index) == NULL) - { - btAlignedObjectArray<btVector3> projections; - projections.push_back(m_nodeRigidConstraints[i][j].m_normal); - m_projectionsDict.insert(index, projections); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - projections.push_back(m_nodeRigidConstraints[i][j].m_normal); - } - } - } - for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j) - { - const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face; - for (int k = 0; k < 3; ++k) - { - const btSoftBody::Node* node = face->m_n[k]; - int index = node->index; - if (m_faceRigidConstraints[i][j].m_static) + btReducedVector rv(dof); + for (int k = 0; k < 3; ++k) { - if (m_projectionsDict.find(index) == NULL) - { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - for (int k = 0; k < 3; ++k) - { - projections.push_back(units[k]); - } - } - } - else - { - if (m_projectionsDict.find(index) == NULL) - { - btAlignedObjectArray<btVector3> projections; - projections.push_back(m_faceRigidConstraints[i][j].m_normal); - m_projectionsDict.insert(index, projections); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - projections.push_back(m_faceRigidConstraints[i][j].m_normal); - } + rv.m_indices.push_back(face->m_n[k]->index); + rv.m_vecs.push_back(bary[k] * m_faceRigidConstraints[i][j].m_normal); + rv.sort(); } + m_projections.push_back(rv); } } - for (int j = 0; j < m_deformableConstraints[i].size(); ++j) - { - const btSoftBody::Face* face = m_deformableConstraints[i][j].m_face; - for (int k = 0; k < 3; ++k) - { - const btSoftBody::Node* node = face->m_n[k]; - int index = node->index; - if (m_deformableConstraints[i][j].m_static) - { - if (m_projectionsDict.find(index) == NULL) - { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - for (int k = 0; k < 3; ++k) - { - projections.push_back(units[k]); - } - } - } - else - { - if (m_projectionsDict.find(index) == NULL) - { - btAlignedObjectArray<btVector3> projections; - projections.push_back(m_deformableConstraints[i][j].m_normal); - m_projectionsDict.insert(index, projections); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - projections.push_back(m_deformableConstraints[i][j].m_normal); - } - } - } + } + btModifiedGramSchmidt<btReducedVector> mgs(m_projections); + mgs.solve(); + m_projections = mgs.m_out; +#endif +} + +void btDeformableContactProjection::checkConstraints(const TVStack& x) +{ + for (int i = 0; i < m_lagrangeMultipliers.size(); ++i) + { + btVector3 d(0,0,0); + const LagrangeMultiplier& lm = m_lagrangeMultipliers[i]; + for (int j = 0; j < lm.m_num_constraints; ++j) + { + for (int k = 0; k < lm.m_num_nodes; ++k) + { + d[j] += lm.m_weights[k] * x[lm.m_indices[k]].dot(lm.m_dirs[j]); + } + } + printf("d = %f, %f, %f\n",d[0],d[1],d[2]); + } +} + +void btDeformableContactProjection::setLagrangeMultiplier() +{ + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (!psb->isActive()) + { + continue; + } + for (int j = 0; j < m_staticConstraints[i].size(); ++j) + { + int index = m_staticConstraints[i][j].m_node->index; + m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY; + LagrangeMultiplier lm; + lm.m_num_nodes = 1; + lm.m_indices[0] = index; + lm.m_weights[0] = 1.0; + lm.m_num_constraints = 3; + lm.m_dirs[0] = btVector3(1,0,0); + lm.m_dirs[1] = btVector3(0,1,0); + lm.m_dirs[2] = btVector3(0,0,1); + m_lagrangeMultipliers.push_back(lm); + } + for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j) + { + int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index; + m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY; + LagrangeMultiplier lm; + lm.m_num_nodes = 1; + lm.m_indices[0] = index; + lm.m_weights[0] = 1.0; + lm.m_num_constraints = 3; + lm.m_dirs[0] = btVector3(1,0,0); + lm.m_dirs[1] = btVector3(0,1,0); + lm.m_dirs[2] = btVector3(0,0,1); + m_lagrangeMultipliers.push_back(lm); + } + for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j) + { + int index = m_nodeRigidConstraints[i][j].m_node->index; + m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset; + LagrangeMultiplier lm; + lm.m_num_nodes = 1; + lm.m_indices[0] = index; + lm.m_weights[0] = 1.0; + if (m_nodeRigidConstraints[i][j].m_static) + { + lm.m_num_constraints = 3; + lm.m_dirs[0] = btVector3(1,0,0); + lm.m_dirs[1] = btVector3(0,1,0); + lm.m_dirs[2] = btVector3(0,0,1); + } + else + { + lm.m_num_constraints = 1; + lm.m_dirs[0] = m_nodeRigidConstraints[i][j].m_normal; + } + m_lagrangeMultipliers.push_back(lm); + } + for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j) + { + const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face; - const btSoftBody::Node* node = m_deformableConstraints[i][j].m_node; - int index = node->index; - if (m_deformableConstraints[i][j].m_static) + btVector3 bary = m_faceRigidConstraints[i][j].getContact()->m_bary; + btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset; + LagrangeMultiplier lm; + lm.m_num_nodes = 3; + for (int k = 0; k<3; ++k) { - if (m_projectionsDict.find(index) == NULL) - { - m_projectionsDict.insert(index, units); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - for (int k = 0; k < 3; ++k) - { - projections.push_back(units[k]); - } - } + face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration); + lm.m_indices[k] = face->m_n[k]->index; + lm.m_weights[k] = bary[k]; + } + if (m_faceRigidConstraints[i][j].m_static) + { + lm.m_num_constraints = 3; + lm.m_dirs[0] = btVector3(1,0,0); + lm.m_dirs[1] = btVector3(0,1,0); + lm.m_dirs[2] = btVector3(0,0,1); } else { - if (m_projectionsDict.find(index) == NULL) - { - btAlignedObjectArray<btVector3> projections; - projections.push_back(m_deformableConstraints[i][j].m_normal); - m_projectionsDict.insert(index, projections); - } - else - { - btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index]; - projections.push_back(m_deformableConstraints[i][j].m_normal); - } + lm.m_num_constraints = 1; + lm.m_dirs[0] = m_faceRigidConstraints[i][j].m_normal; } + m_lagrangeMultipliers.push_back(lm); } } } - +// void btDeformableContactProjection::applyDynamicFriction(TVStack& f) { for (int i = 0; i < m_softBodies.size(); ++i) @@ -502,7 +622,12 @@ void btDeformableContactProjection::reinitialize(bool nodeUpdated) m_faceRigidConstraints[i].clear(); m_deformableConstraints[i].clear(); } - m_projectionsDict.clear(); +#ifndef USE_MGS + m_projectionsDict.clear(); +#else + m_projections.clear(); +#endif + m_lagrangeMultipliers.clear(); } diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h index 3c4490765e..8d7e94d4fb 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h @@ -21,30 +21,37 @@ #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include "btDeformableContactConstraint.h" #include "LinearMath/btHashMap.h" +#include "LinearMath/btReducedVector.h" +#include "LinearMath/btModifiedGramSchmidt.h" #include <vector> + +struct LagrangeMultiplier +{ + int m_num_constraints; // Number of constraints + int m_num_nodes; // Number of nodes in these constraints + btScalar m_weights[3]; // weights of the nodes involved, same size as m_num_nodes + btVector3 m_dirs[3]; // Constraint directions, same size of m_num_constraints; + int m_indices[3]; // indices of the nodes involved, same size as m_num_nodes; +}; + + class btDeformableContactProjection { public: typedef btAlignedObjectArray<btVector3> TVStack; btAlignedObjectArray<btSoftBody *>& m_softBodies; - -// // map from node index to static constraint -// btHashMap<btHashInt, btDeformableStaticConstraint> m_staticConstraints; -// // map from node index to node rigid constraint -// btHashMap<btHashInt, btAlignedObjectArray<btDeformableNodeRigidContactConstraint> > m_nodeRigidConstraints; -// // map from node index to face rigid constraint -// btHashMap<btHashInt, btAlignedObjectArray<btDeformableFaceRigidContactConstraint*> > m_faceRigidConstraints; -// // map from node index to deformable constraint -// btHashMap<btHashInt, btAlignedObjectArray<btDeformableFaceNodeContactConstraint*> > m_deformableConstraints; -// // map from node index to node anchor constraint -// btHashMap<btHashInt, btDeformableNodeAnchorConstraint> m_nodeAnchorConstraints; // all constraints involving face btAlignedObjectArray<btDeformableContactConstraint*> m_allFaceConstraints; - +#ifndef USE_MGS // map from node index to projection directions btHashMap<btHashInt, btAlignedObjectArray<btVector3> > m_projectionsDict; - +#else + btAlignedObjectArray<btReducedVector> m_projections; +#endif + + btAlignedObjectArray<LagrangeMultiplier> m_lagrangeMultipliers; + // map from node index to static constraint btAlignedObjectArray<btAlignedObjectArray<btDeformableStaticConstraint> > m_staticConstraints; // map from node index to node rigid constraint @@ -56,6 +63,8 @@ public: // map from node index to node anchor constraint btAlignedObjectArray<btAlignedObjectArray<btDeformableNodeAnchorConstraint> > m_nodeAnchorConstraints; + bool m_useStrainLimiting; + btDeformableContactProjection(btAlignedObjectArray<btSoftBody *>& softBodies) : m_softBodies(softBodies) { @@ -72,13 +81,10 @@ public: virtual void applyDynamicFriction(TVStack& f); // update and solve the constraints - virtual btScalar update(btCollisionObject** deformableBodies,int numDeformableBodies); - - // solve the position error using split impulse - virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal); + virtual btScalar update(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal); // Add constraints to m_constraints. In addition, the constraints that each vertex own are recorded in m_constraintsDict. - virtual void setConstraints(); + virtual void setConstraints(const btContactSolverInfo& infoGlobal); // Set up projections for each vertex by adding the projection direction to virtual void setProjection(); @@ -86,5 +92,9 @@ public: virtual void reinitialize(bool nodeUpdated); virtual void splitImpulseSetup(const btContactSolverInfo& infoGlobal); + + virtual void setLagrangeMultiplier(); + + void checkConstraints(const TVStack& x); }; #endif /* btDeformableContactProjection_h */ diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h index c2a26338e7..2d042df729 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h @@ -114,6 +114,8 @@ public: { } + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){} + virtual btDeformableLagrangianForceType getForceType() { return BT_COROTATED_FORCE; diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h index 33e5a8564a..13ee3eacb6 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h @@ -50,6 +50,8 @@ public: { } + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){} + virtual void addScaledGravityForce(btScalar scale, TVStack& force) { int numNodes = getNumNodes(); diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h index 64e80e23b3..0b6447442d 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h @@ -26,7 +26,8 @@ enum btDeformableLagrangianForceType BT_MASSSPRING_FORCE = 2, BT_COROTATED_FORCE = 3, BT_NEOHOOKEAN_FORCE = 4, - BT_LINEAR_ELASTICITY_FORCE = 5 + BT_LINEAR_ELASTICITY_FORCE = 5, + BT_MOUSE_PICKING_FORCE = 6 }; static inline double randomDouble(double low, double high) @@ -53,6 +54,9 @@ public: // add damping df virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0; + // build diagonal of A matrix + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA) = 0; + // add elastic df virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0; @@ -85,6 +89,11 @@ public: m_softBodies.push_back(psb); } + virtual void removeSoftBody(btSoftBody* psb) + { + m_softBodies.remove(psb); + } + virtual void setIndices(const btAlignedObjectArray<btSoftBody::Node*>* nodes) { m_nodes = nodes; diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h index 54b4e4481d..b128df92cc 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h @@ -149,6 +149,52 @@ public: } } + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA) + { + // implicit damping force differential + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (!psb->isActive()) + { + continue; + } + btScalar scaled_k_damp = m_dampingStiffness * scale; + for (int j = 0; j < psb->m_links.size(); ++j) + { + const btSoftBody::Link& link = psb->m_links[j]; + btSoftBody::Node* node1 = link.m_n[0]; + btSoftBody::Node* node2 = link.m_n[1]; + size_t id1 = node1->index; + size_t id2 = node2->index; + if (m_momentum_conserving) + { + if ((node2->m_x - node1->m_x).norm() > SIMD_EPSILON) + { + btVector3 dir = (node2->m_x - node1->m_x).normalized(); + for (int d = 0; d < 3; ++d) + { + if (node1->m_im > 0) + diagA[id1][d] -= scaled_k_damp * dir[d] * dir[d]; + if (node2->m_im > 0) + diagA[id2][d] -= scaled_k_damp * dir[d] * dir[d]; + } + } + } + else + { + for (int d = 0; d < 3; ++d) + { + if (node1->m_im > 0) + diagA[id1][d] -= scaled_k_damp; + if (node2->m_im > 0) + diagA[id2][d] -= scaled_k_damp; + } + } + } + } + } + virtual double totalElasticEnergy(btScalar dt) { double energy = 0; diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h new file mode 100644 index 0000000000..07c10935f4 --- /dev/null +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h @@ -0,0 +1,145 @@ +/* + Written by Xuchen Han <xuchenhan2015@u.northwestern.edu> + + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2019 Google Inc. http://bulletphysics.org + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it freely, + subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef BT_MOUSE_PICKING_FORCE_H +#define BT_MOUSE_PICKING_FORCE_H + +#include "btDeformableLagrangianForce.h" + +class btDeformableMousePickingForce : public btDeformableLagrangianForce +{ + // If true, the damping force will be in the direction of the spring + // If false, the damping force will be in the direction of the velocity + btScalar m_elasticStiffness, m_dampingStiffness; + const btSoftBody::Face& m_face; + btVector3 m_mouse_pos; + btScalar m_maxForce; +public: + typedef btAlignedObjectArray<btVector3> TVStack; + btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, btVector3 mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce) + { + } + + virtual void addScaledForces(btScalar scale, TVStack& force) + { + addScaledDampingForce(scale, force); + addScaledElasticForce(scale, force); + } + + virtual void addScaledExplicitForce(btScalar scale, TVStack& force) + { + addScaledElasticForce(scale, force); + } + + virtual void addScaledDampingForce(btScalar scale, TVStack& force) + { + for (int i = 0; i < 3; ++i) + { + btVector3 v_diff = m_face.m_n[i]->m_v; + btVector3 scaled_force = scale * m_dampingStiffness * v_diff; + if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON) + { + btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized(); + scaled_force = scale * m_dampingStiffness * v_diff.dot(dir) * dir; + } + force[m_face.m_n[i]->index] -= scaled_force; + } + } + + virtual void addScaledElasticForce(btScalar scale, TVStack& force) + { + btScalar scaled_stiffness = scale * m_elasticStiffness; + for (int i = 0; i < 3; ++i) + { + btVector3 dir = (m_face.m_n[i]->m_q - m_mouse_pos); + btVector3 scaled_force = scaled_stiffness * dir; + if (scaled_force.safeNorm() > m_maxForce) + { + scaled_force.safeNormalize(); + scaled_force *= m_maxForce; + } + force[m_face.m_n[i]->index] -= scaled_force; + } + } + + virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) + { + btScalar scaled_k_damp = m_dampingStiffness * scale; + for (int i = 0; i < 3; ++i) + { + btVector3 local_scaled_df = scaled_k_damp * dv[m_face.m_n[i]->index]; + if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON) + { + btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized(); + local_scaled_df= scaled_k_damp * dv[m_face.m_n[i]->index].dot(dir) * dir; + } + df[m_face.m_n[i]->index] -= local_scaled_df; + } + } + + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){} + + virtual double totalElasticEnergy(btScalar dt) + { + double energy = 0; + for (int i = 0; i < 3; ++i) + { + btVector3 dir = (m_face.m_n[i]->m_q - m_mouse_pos); + btVector3 scaled_force = m_elasticStiffness * dir; + if (scaled_force.safeNorm() > m_maxForce) + { + scaled_force.safeNormalize(); + scaled_force *= m_maxForce; + } + energy += 0.5 * scaled_force.dot(dir); + } + return energy; + } + + virtual double totalDampingEnergy(btScalar dt) + { + double energy = 0; + for (int i = 0; i < 3; ++i) + { + btVector3 v_diff = m_face.m_n[i]->m_v; + btVector3 scaled_force = m_dampingStiffness * v_diff; + if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON) + { + btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized(); + scaled_force = m_dampingStiffness * v_diff.dot(dir) * dir; + } + energy -= scaled_force.dot(m_face.m_n[i]->m_v) / dt; + } + return energy; + } + + virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) + { + //TODO + } + + void setMousePos(const btVector3& p) + { + m_mouse_pos = p; + } + + virtual btDeformableLagrangianForceType getForceType() + { + return BT_MOUSE_PICKING_FORCE; + } + +}; + +#endif /* btMassSpring_h */ diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp index 06f95d69f6..c8cc47923e 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp @@ -32,7 +32,7 @@ btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(b m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); // solver body velocity -> rigid body velocity solverBodyWriteBack(infoGlobal); - btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies,numDeformableBodies); + btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies,numDeformableBodies, infoGlobal); // update rigid body velocity in rigid/deformable contact m_leastSquaresResidual = btMax(m_leastSquaresResidual, deformableResidual); // solver body velocity <- rigid body velocity @@ -112,7 +112,7 @@ void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseI if (infoGlobal.m_splitImpulse) { { - m_deformableSolver->splitImpulseSetup(infoGlobal); +// m_deformableSolver->splitImpulseSetup(infoGlobal); for (iteration = 0; iteration < infoGlobal.m_numIterations; iteration++) { btScalar leastSquaresResidual = 0.f; @@ -127,8 +127,8 @@ void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseI leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); } // solve the position correction between deformable and rigid/multibody - btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal); - leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); +// btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal); +// leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); } if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1)) { diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp index 618e5c0d7b..6b742978ef 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp @@ -22,7 +22,6 @@ Call internalStepSimulation multiple times, to achieve 240Hz (4 steps of 60Hz). 2. Detect discrete collisions between rigid and deformable bodies at position x_{n+1}^* = x_n + dt * v_{n+1}^*. 3a. Solve all constraints, including LCP. Contact, position correction due to numerical drift, friction, and anchors for deformable. - TODO: add option for positional drift correction (using vel_target += erp * pos_error/dt 3b. 5 Newton steps (multiple step). Conjugent Gradient solves linear system. Deformable Damping: Then velocities of deformable bodies v_{n+1} are solved in M(v_{n+1} - v_{n+1}^*) = damping_force * dt / mass, @@ -58,14 +57,20 @@ m_deformableBodySolver(deformableBodySolver), m_solverCallback(0) m_sbi.water_density = 0; m_sbi.water_offset = 0; m_sbi.water_normal = btVector3(0, 0, 0); - m_sbi.m_gravity.setValue(0, -10, 0); + m_sbi.m_gravity.setValue(0, -9.8, 0); m_internalTime = 0.0; m_implicit = false; m_lineSearch = false; - m_selfCollision = true; + m_useProjection = true; + m_ccdIterations = 5; m_solverDeformableBodyIslandCallback = new DeformableBodyInplaceSolverIslandCallback(constraintSolver, dispatcher); } +btDeformableMultiBodyDynamicsWorld::~btDeformableMultiBodyDynamicsWorld() +{ + delete m_solverDeformableBodyIslandCallback; +} + void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { BT_PROFILE("internalSingleStepSimulation"); @@ -74,20 +79,16 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t (*m_internalPreTickCallback)(this, timeStep); } reinitialize(timeStep); + // add gravity to velocity of rigid and multi bodys applyRigidBodyGravity(timeStep); ///apply gravity and explicit force to velocity, predict motion predictUnconstraintMotion(timeStep); - ///perform collision detection + ///perform collision detection that involves rigid/multi bodies btMultiBodyDynamicsWorld::performDiscreteCollisionDetection(); - if (m_selfCollision) - { - softBodySelfCollision(); - } - btMultiBodyDynamicsWorld::calculateSimulationIslands(); beforeSolverCallbacks(timeStep); @@ -96,7 +97,13 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t solveConstraints(timeStep); afterSolverCallbacks(timeStep); - + + performDeformableCollisionDetection(); + + applyRepulsionForce(timeStep); + + performGeometricCollisions(timeStep); + integrateTransforms(timeStep); ///update vehicle simulation @@ -107,6 +114,27 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t // /////////////////////////////// } +void btDeformableMultiBodyDynamicsWorld::performDeformableCollisionDetection() +{ + for (int i = 0; i < m_softBodies.size(); ++i) + { + m_softBodies[i]->m_softSoftCollision = true; + } + + for (int i = 0; i < m_softBodies.size(); ++i) + { + for (int j = i; j < m_softBodies.size(); ++j) + { + m_softBodies[i]->defaultCollisionHandler(m_softBodies[j]); + } + } + + for (int i = 0; i < m_softBodies.size(); ++i) + { + m_softBodies[i]->m_softSoftCollision = false; + } +} + void btDeformableMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep) { for (int i = 0; i < m_softBodies.size(); i++) @@ -131,10 +159,106 @@ void btDeformableMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep btMultiBodyDynamicsWorld::updateActivationState(timeStep); } +void btDeformableMultiBodyDynamicsWorld::applyRepulsionForce(btScalar timeStep) +{ + BT_PROFILE("btDeformableMultiBodyDynamicsWorld::applyRepulsionForce"); + for (int i = 0; i < m_softBodies.size(); i++) + { + btSoftBody* psb = m_softBodies[i]; + if (psb->isActive()) + { + psb->applyRepulsionForce(timeStep, true); + } + } +} + +void btDeformableMultiBodyDynamicsWorld::performGeometricCollisions(btScalar timeStep) +{ + BT_PROFILE("btDeformableMultiBodyDynamicsWorld::performGeometricCollisions"); + // refit the BVH tree for CCD + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (psb->isActive()) + { + m_softBodies[i]->updateFaceTree(true, false); + m_softBodies[i]->updateNodeTree(true, false); + for (int j = 0; j < m_softBodies[i]->m_faces.size(); ++j) + { + btSoftBody::Face& f = m_softBodies[i]->m_faces[j]; + f.m_n0 = (f.m_n[1]->m_x - f.m_n[0]->m_x).cross(f.m_n[2]->m_x - f.m_n[0]->m_x); + } + } + } + + // clear contact points & update DBVT + for (int r = 0; r < m_ccdIterations; ++r) + { + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (psb->isActive()) + { + // clear contact points in the previous iteration + psb->m_faceNodeContacts.clear(); + + // update m_q and normals for CCD calculation + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + psb->m_nodes[j].m_q = psb->m_nodes[j].m_x + timeStep * psb->m_nodes[j].m_v; + } + for (int j = 0; j < psb->m_faces.size(); ++j) + { + btSoftBody::Face& f = psb->m_faces[j]; + f.m_n1 = (f.m_n[1]->m_q - f.m_n[0]->m_q).cross(f.m_n[2]->m_q - f.m_n[0]->m_q); + f.m_vn = (f.m_n[1]->m_v - f.m_n[0]->m_v).cross(f.m_n[2]->m_v - f.m_n[0]->m_v) * timeStep * timeStep; + } + } + } + + // apply CCD to register new contact points + for (int i = 0; i < m_softBodies.size(); ++i) + { + for (int j = i; j < m_softBodies.size(); ++j) + { + btSoftBody* psb1 = m_softBodies[i]; + btSoftBody* psb2 = m_softBodies[j]; + if (psb1->isActive() && psb2->isActive()) + { + m_softBodies[i]->geometricCollisionHandler(m_softBodies[j]); + } + } + } + + int penetration_count = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (psb->isActive()) + { + penetration_count += psb->m_faceNodeContacts.size(); + } + } + if (penetration_count == 0) + { + break; + } + + // apply inelastic impulse + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + if (psb->isActive()) + { + psb->applyRepulsionForce(timeStep, false); + } + } + } +} void btDeformableMultiBodyDynamicsWorld::softBodySelfCollision() { - m_deformableBodySolver->updateSoftBodies(); + BT_PROFILE("btDeformableMultiBodyDynamicsWorld::softBodySelfCollision"); for (int i = 0; i < m_softBodies.size(); i++) { btSoftBody* psb = m_softBodies[i]; @@ -192,8 +316,6 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) } } node.m_x = node.m_x + timeStep * node.m_v; - node.m_v -= node.m_vsplit; - node.m_vsplit.setZero(); node.m_q = node.m_x; node.m_vn = node.m_v; } @@ -255,6 +377,7 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep) { + BT_PROFILE("btDeformableMultiBodyDynamicsWorld::solveConstraints"); // save v_{n+1}^* velocity after explicit forces m_deformableBodySolver->backupVelocity(); @@ -265,8 +388,11 @@ void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep) solveContactConstraints(); // set up the directions in which the velocity does not change in the momentum solve - m_deformableBodySolver->m_objective->m_projection.setProjection(); - + if (m_useProjection) + m_deformableBodySolver->m_objective->m_projection.setProjection(); + else + m_deformableBodySolver->m_objective->m_projection.setLagrangeMultiplier(); + // for explicit scheme, m_backupVelocity = v_{n+1}^* // for implicit scheme, m_backupVelocity = v_n // Here, set dv = v_{n+1} - v_n for nodes in contact @@ -280,7 +406,7 @@ void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep) void btDeformableMultiBodyDynamicsWorld::setupConstraints() { // set up constraints between multibody and deformable bodies - m_deformableBodySolver->setConstraints(); + m_deformableBodySolver->setConstraints(m_solverInfo); // set up constraints among multibodies { @@ -403,6 +529,17 @@ void btDeformableMultiBodyDynamicsWorld::reinitialize(btScalar timeStep) dispatchInfo.m_stepCount = 0; dispatchInfo.m_debugDraw = btMultiBodyDynamicsWorld::getDebugDrawer(); btMultiBodyDynamicsWorld::getSolverInfo().m_timeStep = timeStep; + if (m_useProjection) + { + m_deformableBodySolver->m_useProjection = true; +// m_deformableBodySolver->m_objective->m_projection.m_useStrainLimiting = true; + m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_massPreconditioner; + } + else + { + m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_KKTPreconditioner; + } + } @@ -566,6 +703,24 @@ void btDeformableMultiBodyDynamicsWorld::addForce(btSoftBody* psb, btDeformableL } } +void btDeformableMultiBodyDynamicsWorld::removeForce(btSoftBody* psb, btDeformableLagrangianForce* force) +{ + btAlignedObjectArray<btDeformableLagrangianForce*>& forces = m_deformableBodySolver->m_objective->m_lf; + int removed_index = -1; + for (int i = 0; i < forces.size(); ++i) + { + if (forces[i]->getForceType() == force->getForceType()) + { + forces[i]->removeSoftBody(psb); + if (forces[i]->m_softBodies.size() == 0) + removed_index = i; + break; + } + } + if (removed_index >= 0) + forces.removeAtIndex(removed_index); +} + void btDeformableMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body) { m_softBodies.remove(body); diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h index 7630385767..76b58a0378 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h @@ -46,10 +46,10 @@ class btDeformableMultiBodyDynamicsWorld : public btMultiBodyDynamicsWorld bool m_drawClusterTree; btSoftBodyWorldInfo m_sbi; btScalar m_internalTime; - int m_contact_iterations; + int m_ccdIterations; bool m_implicit; bool m_lineSearch; - bool m_selfCollision; + bool m_useProjection; DeformableBodyInplaceSolverIslandCallback* m_solverDeformableBodyIslandCallback; typedef void (*btSolverCallback)(btScalar time, btDeformableMultiBodyDynamicsWorld* world); @@ -80,9 +80,7 @@ public: m_solverCallback = cb; } - virtual ~btDeformableMultiBodyDynamicsWorld() - { - } + virtual ~btDeformableMultiBodyDynamicsWorld(); virtual btMultiBodyDynamicsWorld* getMultiBodyDynamicsWorld() { @@ -133,6 +131,8 @@ public: void addForce(btSoftBody* psb, btDeformableLagrangianForce* force); + void removeForce(btSoftBody* psb, btDeformableLagrangianForce* force); + void removeSoftBody(btSoftBody* body); void removeCollisionObject(btCollisionObject* collisionObject); @@ -142,6 +142,8 @@ public: void setupConstraints(); + void performDeformableCollisionDetection(); + void solveMultiBodyConstraints(); void solveContactConstraints(); @@ -159,7 +161,151 @@ public: { m_lineSearch = lineSearch; } + + void applyRepulsionForce(btScalar timeStep); + + void performGeometricCollisions(btScalar timeStep); + + struct btDeformableSingleRayCallback : public btBroadphaseRayCallback + { + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; + + const btDeformableMultiBodyDynamicsWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; + + btDeformableSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btDeformableMultiBodyDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) + { + m_rayFromTrans.setIdentity(); + m_rayFromTrans.setOrigin(m_rayFromWorld); + m_rayToTrans.setIdentity(); + m_rayToTrans.setOrigin(m_rayToWorld); + + btVector3 rayDir = (rayToWorld - rayFromWorld); + + rayDir.normalize(); + ///what about division by zero? --> just set rayDirection[i] to INF/1e30 + m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; + m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; + m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; + m_signs[0] = m_rayDirectionInverse[0] < 0.0; + m_signs[1] = m_rayDirectionInverse[1] < 0.0; + m_signs[2] = m_rayDirectionInverse[2] < 0.0; + + m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld); + } + + virtual bool process(const btBroadphaseProxy* proxy) + { + ///terminate further ray tests, once the closestHitFraction reached zero + if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) + return false; + + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + + //only perform raycast if filterMask matches + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; +#if 0 +#ifdef RECALCULATE_AABB + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); +#else + //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax); + const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; + const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; +#endif +#endif + //btScalar hitLambda = m_resultCallback.m_closestHitFraction; + //culling already done by broadphase + //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) + { + m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); + } + } + return true; + } + }; + + + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const + { + BT_PROFILE("rayTest"); + /// use the broadphase to accelerate the search for objects, based on their aabb + /// and for each object with ray-aabb overlap, perform an exact ray test + btDeformableSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback); + +#ifndef USE_BRUTEFORCE_RAYBROADPHASE + m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB); +#else + for (int i = 0; i < this->getNumCollisionObjects(); i++) + { + rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE + } + + void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) const + { + if (collisionShape->isSoftBody()) + { + btSoftBody* softBody = btSoftBody::upcast(collisionObject); + if (softBody) + { + btSoftBody::sRayCast softResult; + if (softBody->rayFaceTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) + { + if (softResult.fraction <= resultCallback.m_closestHitFraction) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = 0; + shapeInfo.m_triangleIndex = softResult.index; + // get the normal + btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin(); + btVector3 normal = -rayDir; + normal.normalize(); + { + normal = softBody->m_faces[softResult.index].m_normal; + if (normal.dot(rayDir) > 0) + { + // normal always point toward origin of the ray + normal = -normal; + } + } + + btCollisionWorld::LocalRayResult rayResult(collisionObject, + &shapeInfo, + normal, + softResult.fraction); + bool normalInWorldSpace = true; + resultCallback.addSingleResult(rayResult, normalInWorldSpace); + } + } + } + } + else + { + btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback); + } + } }; #endif //BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h index 3d06e304d2..d89bc4aca4 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h @@ -24,21 +24,65 @@ class btDeformableNeoHookeanForce : public btDeformableLagrangianForce { public: typedef btAlignedObjectArray<btVector3> TVStack; - btScalar m_mu, m_lambda; + btScalar m_mu, m_lambda; // Lame Parameters + btScalar m_E, m_nu; // Young's modulus and Poisson ratio btScalar m_mu_damp, m_lambda_damp; btDeformableNeoHookeanForce(): m_mu(1), m_lambda(1) { btScalar damping = 0.05; m_mu_damp = damping * m_mu; m_lambda_damp = damping * m_lambda; + updateYoungsModulusAndPoissonRatio(); } btDeformableNeoHookeanForce(btScalar mu, btScalar lambda, btScalar damping = 0.05): m_mu(mu), m_lambda(lambda) { m_mu_damp = damping * m_mu; m_lambda_damp = damping * m_lambda; + updateYoungsModulusAndPoissonRatio(); } - + + void updateYoungsModulusAndPoissonRatio() + { + // conversion from Lame Parameters to Young's modulus and Poisson ratio + // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters + m_E = m_mu * (3*m_lambda + 2*m_mu)/(m_lambda + m_mu); + m_nu = m_lambda * 0.5 / (m_mu + m_lambda); + } + + void updateLameParameters() + { + // conversion from Young's modulus and Poisson ratio to Lame Parameters + // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters + m_mu = m_E * 0.5 / (1 + m_nu); + m_lambda = m_E * m_nu / ((1 + m_nu) * (1- 2*m_nu)); + } + + void setYoungsModulus(btScalar E) + { + m_E = E; + updateLameParameters(); + } + + void setPoissonRatio(btScalar nu) + { + m_nu = nu; + updateLameParameters(); + } + + void setDamping(btScalar damping) + { + m_mu_damp = damping * m_mu; + m_lambda_damp = damping * m_lambda; + } + + void setLameParameters(btScalar mu, btScalar lambda) + { + m_mu = mu; + m_lambda = lambda; + updateYoungsModulusAndPoissonRatio(); + } + virtual void addScaledForces(btScalar scale, TVStack& force) { addScaledDampingForce(scale, force); @@ -269,6 +313,8 @@ public: } } + virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){} + virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) { int numNodes = getNumNodes(); diff --git a/thirdparty/bullet/BulletSoftBody/btPreconditioner.h b/thirdparty/bullet/BulletSoftBody/btPreconditioner.h index d712420381..c2db448ef8 100644 --- a/thirdparty/bullet/BulletSoftBody/btPreconditioner.h +++ b/thirdparty/bullet/BulletSoftBody/btPreconditioner.h @@ -68,12 +68,221 @@ public: virtual void operator()(const TVStack& x, TVStack& b) { btAssert(b.size() == x.size()); - btAssert(m_inv_mass.size() == x.size()); - for (int i = 0; i < b.size(); ++i) + btAssert(m_inv_mass.size() <= x.size()); + for (int i = 0; i < m_inv_mass.size(); ++i) { b[i] = x[i] * m_inv_mass[i]; } + for (int i = m_inv_mass.size(); i < b.size(); ++i) + { + b[i] = x[i]; + } + } +}; + + +class KKTPreconditioner : public Preconditioner +{ + const btAlignedObjectArray<btSoftBody *>& m_softBodies; + const btDeformableContactProjection& m_projections; + const btAlignedObjectArray<btDeformableLagrangianForce*>& m_lf; + TVStack m_inv_A, m_inv_S; + const btScalar& m_dt; + const bool& m_implicit; +public: + KKTPreconditioner(const btAlignedObjectArray<btSoftBody *>& softBodies, const btDeformableContactProjection& projections, const btAlignedObjectArray<btDeformableLagrangianForce*>& lf, const btScalar& dt, const bool& implicit) + : m_softBodies(softBodies) + , m_projections(projections) + , m_lf(lf) + , m_dt(dt) + , m_implicit(implicit) + { + } + + virtual void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + { + int num_nodes = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + num_nodes += psb->m_nodes.size(); + } + m_inv_A.resize(num_nodes); + } + buildDiagonalA(m_inv_A); + for (int i = 0; i < m_inv_A.size(); ++i) + { +// printf("A[%d] = %f, %f, %f \n", i, m_inv_A[i][0], m_inv_A[i][1], m_inv_A[i][2]); + for (int d = 0; d < 3; ++d) + { + m_inv_A[i][d] = (m_inv_A[i][d] == 0) ? 0.0 : 1.0/ m_inv_A[i][d]; + } + } + m_inv_S.resize(m_projections.m_lagrangeMultipliers.size()); +// printf("S.size() = %d \n", m_inv_S.size()); + buildDiagonalS(m_inv_A, m_inv_S); + for (int i = 0; i < m_inv_S.size(); ++i) + { +// printf("S[%d] = %f, %f, %f \n", i, m_inv_S[i][0], m_inv_S[i][1], m_inv_S[i][2]); + for (int d = 0; d < 3; ++d) + { + m_inv_S[i][d] = (m_inv_S[i][d] == 0) ? 0.0 : 1.0/ m_inv_S[i][d]; + } + } + } + + void buildDiagonalA(TVStack& diagA) const + { + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + const btSoftBody::Node& node = psb->m_nodes[j]; + diagA[counter] = (node.m_im == 0) ? btVector3(0,0,0) : btVector3(1.0/node.m_im, 1.0 / node.m_im, 1.0 / node.m_im); + ++counter; + } + } + if (m_implicit) + { + printf("implicit not implemented\n"); + btAssert(false); + } + for (int i = 0; i < m_lf.size(); ++i) + { + // add damping matrix + m_lf[i]->buildDampingForceDifferentialDiagonal(-m_dt, diagA); + } + } + + void buildDiagonalS(const TVStack& inv_A, TVStack& diagS) + { + for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c) + { + // S[k,k] = e_k^T * C A_d^-1 C^T * e_k + const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c]; + btVector3& t = diagS[c]; + t.setZero(); + for (int j = 0; j < lm.m_num_constraints; ++j) + { + for (int i = 0; i < lm.m_num_nodes; ++i) + { + for (int d = 0; d < 3; ++d) + { + t[j] += inv_A[lm.m_indices[i]][d] * lm.m_dirs[j][d] * lm.m_dirs[j][d] * lm.m_weights[i] * lm.m_weights[i]; + } + } + } + } + } +#define USE_FULL_PRECONDITIONER +#ifndef USE_FULL_PRECONDITIONER + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + for (int i = 0; i < m_inv_A.size(); ++i) + { + b[i] = x[i] * m_inv_A[i]; + } + int offset = m_inv_A.size(); + for (int i = 0; i < m_inv_S.size(); ++i) + { + b[i+offset] = x[i+offset] * m_inv_S[i]; + } + } +#else + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + int offset = m_inv_A.size(); + + for (int i = 0; i < m_inv_A.size(); ++i) + { + b[i] = x[i] * m_inv_A[i]; + } + + for (int i = 0; i < m_inv_S.size(); ++i) + { + b[i+offset].setZero(); + } + + for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c) + { + const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c]; + // C * x + for (int d = 0; d < lm.m_num_constraints; ++d) + { + for (int i = 0; i < lm.m_num_nodes; ++i) + { + b[offset+c][d] += lm.m_weights[i] * b[lm.m_indices[i]].dot(lm.m_dirs[d]); + } + } + } + + for (int i = 0; i < m_inv_S.size(); ++i) + { + b[i+offset] = b[i+offset] * m_inv_S[i]; + } + + for (int i = 0; i < m_inv_A.size(); ++i) + { + b[i].setZero(); + } + + for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c) + { + // C^T * lambda + const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c]; + for (int i = 0; i < lm.m_num_nodes; ++i) + { + for (int j = 0; j < lm.m_num_constraints; ++j) + { + b[lm.m_indices[i]] += b[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j]; + } + } + } + + for (int i = 0; i < m_inv_A.size(); ++i) + { + b[i] = (x[i] - b[i]) * m_inv_A[i]; + } + + TVStack t; + t.resize(b.size()); + for (int i = 0; i < m_inv_S.size(); ++i) + { + t[i+offset] = x[i+offset] * m_inv_S[i]; + } + for (int i = 0; i < m_inv_A.size(); ++i) + { + t[i].setZero(); + } + for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c) + { + // C^T * lambda + const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c]; + for (int i = 0; i < lm.m_num_nodes; ++i) + { + for (int j = 0; j < lm.m_num_constraints; ++j) + { + t[lm.m_indices[i]] += t[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j]; + } + } + } + for (int i = 0; i < m_inv_A.size(); ++i) + { + b[i] += t[i] * m_inv_A[i]; + } + + for (int i = 0; i < m_inv_S.size(); ++i) + { + b[i+offset] -= x[i+offset] * m_inv_S[i]; + } } +#endif }; #endif /* BT_PRECONDITIONER_H */ diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp index 2a458b1d80..81b846d7f8 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp +++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp @@ -18,6 +18,7 @@ subject to the following restrictions: #include "BulletSoftBody/btSoftBodySolvers.h" #include "btSoftBodyData.h" #include "LinearMath/btSerializer.h" +#include "LinearMath/btImplicitQRSVD.h" #include "LinearMath/btAlignedAllocator.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" @@ -25,6 +26,107 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleShape.h" #include <iostream> // +static inline btDbvtNode* buildTreeBottomUp(btAlignedObjectArray<btDbvtNode*>& leafNodes, btAlignedObjectArray<btAlignedObjectArray<int> >& adj) +{ + int N = leafNodes.size(); + if (N == 0) + { + return NULL; + } + while (N > 1) + { + btAlignedObjectArray<bool> marked; + btAlignedObjectArray<btDbvtNode*> newLeafNodes; + btAlignedObjectArray<std::pair<int,int> > childIds; + btAlignedObjectArray<btAlignedObjectArray<int> > newAdj; + marked.resize(N); + for (int i = 0; i < N; ++i) + marked[i] = false; + + // pair adjacent nodes into new(parent) node + for (int i = 0; i < N; ++i) + { + if (marked[i]) + continue; + bool merged = false; + for (int j = 0; j < adj[i].size(); ++j) + { + int n = adj[i][j]; + if (!marked[adj[i][j]]) + { + btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode(); + node->parent = NULL; + node->childs[0] = leafNodes[i]; + node->childs[1] = leafNodes[n]; + leafNodes[i]->parent = node; + leafNodes[n]->parent = node; + newLeafNodes.push_back(node); + childIds.push_back(std::make_pair(i,n)); + merged = true; + marked[n] = true; + break; + } + } + if (!merged) + { + newLeafNodes.push_back(leafNodes[i]); + childIds.push_back(std::make_pair(i,-1)); + } + marked[i] = true; + } + // update adjacency matrix + newAdj.resize(newLeafNodes.size()); + for (int i = 0; i < newLeafNodes.size(); ++i) + { + for (int j = i+1; j < newLeafNodes.size(); ++j) + { + bool neighbor = false; + const btAlignedObjectArray<int>& leftChildNeighbors = adj[childIds[i].first]; + for (int k = 0; k < leftChildNeighbors.size(); ++k) + { + if (leftChildNeighbors[k] == childIds[j].first || leftChildNeighbors[k] == childIds[j].second) + { + neighbor = true; + break; + } + } + if (!neighbor && childIds[i].second != -1) + { + const btAlignedObjectArray<int>& rightChildNeighbors = adj[childIds[i].second]; + for (int k = 0; k < rightChildNeighbors.size(); ++k) + { + if (rightChildNeighbors[k] == childIds[j].first || rightChildNeighbors[k] == childIds[j].second) + { + neighbor = true; + break; + } + } + } + if (neighbor) + { + newAdj[i].push_back(j); + newAdj[j].push_back(i); + } + } + } + leafNodes = newLeafNodes; + //this assignment leaks memory, the assignment doesn't do a deep copy, for now a manual copy + //adj = newAdj; + adj.clear(); + adj.resize(newAdj.size()); + for (int i = 0; i < newAdj.size(); i++) + { + for (int j = 0; j < newAdj[i].size(); j++) + { + adj[i].push_back(newAdj[i][j]); + } + } + N = leafNodes.size(); + } + return leafNodes[0]; +} + +// btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m) : m_softBodySolver(0), m_worldInfo(worldInfo) { @@ -41,6 +143,7 @@ btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btV /* Nodes */ const btScalar margin = getCollisionShape()->getMargin(); m_nodes.resize(node_count); + m_X.resize(node_count); for (int i = 0, ni = node_count; i < ni; ++i) { Node& n = m_nodes[i]; @@ -51,8 +154,11 @@ btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btV n.m_im = n.m_im > 0 ? 1 / n.m_im : 0; n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x, margin), &n); n.m_material = pm; + m_X[i] = n.m_x; } updateBounds(); + setCollisionQuadrature(3); + m_fdbvnt = 0; } btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo) @@ -111,15 +217,18 @@ void btSoftBody::initDefaults() m_collisionShape = new btSoftBodyCollisionShape(this); m_collisionShape->setMargin(0.25f); - m_initialWorldTransform.setIdentity(); + m_worldTransform.setIdentity(); m_windVelocity = btVector3(0, 0, 0); m_restLengthScale = btScalar(1.0); - m_dampingCoefficient = 1; - m_sleepingThreshold = 0.1; - m_useFaceContact = true; + m_dampingCoefficient = 1.0; + m_sleepingThreshold = .4; m_useSelfCollision = false; - m_collisionFlags = 0; + m_collisionFlags = 0; + m_softSoftCollision = false; + m_maxSpeedSquared = 0; + m_repulsionStiffness = 0.5; + m_fdbvnt = 0; } // @@ -134,6 +243,8 @@ btSoftBody::~btSoftBody() btAlignedFree(m_materials[i]); for (i = 0; i < m_joints.size(); ++i) btAlignedFree(m_joints[i]); + if (m_fdbvnt) + delete m_fdbvnt; } // @@ -897,6 +1008,71 @@ void btSoftBody::setVolumeDensity(btScalar density) } // +btVector3 btSoftBody::getLinearVelocity() +{ + btVector3 total_momentum = btVector3(0,0,0); + for (int i = 0; i < m_nodes.size(); ++i) + { + btScalar mass = m_nodes[i].m_im == 0 ? 0 : 1.0/m_nodes[i].m_im; + total_momentum += mass * m_nodes[i].m_v; + } + btScalar total_mass = getTotalMass(); + return total_mass == 0 ? total_momentum : total_momentum / total_mass; +} + +// +void btSoftBody::setLinearVelocity(const btVector3& linVel) +{ + btVector3 old_vel = getLinearVelocity(); + btVector3 diff = linVel - old_vel; + for (int i = 0; i < m_nodes.size(); ++i) + m_nodes[i].m_v += diff; +} + +// +void btSoftBody::setAngularVelocity(const btVector3& angVel) +{ + btVector3 old_vel = getLinearVelocity(); + btVector3 com = getCenterOfMass(); + for (int i = 0; i < m_nodes.size(); ++i) + { + m_nodes[i].m_v = angVel.cross(m_nodes[i].m_x - com) + old_vel; + } +} + +// +btTransform btSoftBody::getRigidTransform() +{ + btVector3 t = getCenterOfMass(); + btMatrix3x3 S; + S.setZero(); + // get rotation that minimizes L2 difference: \sum_i || RX_i + t - x_i || + for (int i = 0; i < m_nodes.size(); ++i) + { + S += OuterProduct(m_X[i], t-m_nodes[i].m_x); + } + btVector3 sigma; + btMatrix3x3 U,V; + singularValueDecomposition(S,U,sigma,V); + btMatrix3x3 R = V * U.transpose(); + btTransform trs; + trs.setIdentity(); + trs.setOrigin(t); + trs.setBasis(R); + return trs; +} + +// +void btSoftBody::transformTo(const btTransform& trs) +{ + // get the current best rigid fit + btTransform current_transform = getRigidTransform(); + // apply transform in material space + btTransform new_transform = trs * current_transform.inverse(); + transform(new_transform); +} + +// void btSoftBody::transform(const btTransform& trs) { const btScalar margin = getCollisionShape()->getMargin(); @@ -916,7 +1092,6 @@ void btSoftBody::transform(const btTransform& trs) updateNormals(); updateBounds(); updateConstants(); - m_initialWorldTransform = trs; } // @@ -1834,6 +2009,25 @@ bool btSoftBody::rayTest(const btVector3& rayFrom, return (rayTest(rayFrom, rayTo, results.fraction, results.feature, results.index, false) != 0); } +bool btSoftBody::rayFaceTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results) +{ + if (m_faces.size() == 0) + return false; + else + { + if (m_fdbvt.empty()) + initializeFaceTree(); + } + + results.body = this; + results.fraction = 1.f; + results.index = -1; + + return (rayFaceTest(rayFrom, rayTo, results.fraction, results.index) != 0); +} + // void btSoftBody::setSolver(eSolverPresets::_ preset) { @@ -2339,15 +2533,160 @@ int btSoftBody::rayTest(const btVector3& rayFrom, const btVector3& rayTo, return (cnt); } +int btSoftBody::rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo, + btScalar& mint, int& index) const +{ + int cnt = 0; + { /* Use dbvt */ + RayFromToCaster collider(rayFrom, rayTo, mint); + + btDbvt::rayTest(m_fdbvt.m_root, rayFrom, rayTo, collider); + if (collider.m_face) + { + mint = collider.m_mint; + index = (int)(collider.m_face - &m_faces[0]); + cnt = 1; + } + } + return (cnt); +} + + // +static inline btDbvntNode* copyToDbvnt(const btDbvtNode* n) +{ + if (n == 0) + return 0; + btDbvntNode* root = new btDbvntNode(n); + if (n->isinternal()) + { + btDbvntNode* c0 = copyToDbvnt(n->childs[0]); + root->childs[0] = c0; + btDbvntNode* c1 = copyToDbvnt(n->childs[1]); + root->childs[1] = c1; + } + return root; +} + +static inline void calculateNormalCone(btDbvntNode* root) +{ + if (!root) + return; + if (root->isleaf()) + { + const btSoftBody::Face* face = (btSoftBody::Face*)root->data; + root->normal = face->m_normal; + root->angle = 0; + } + else + { + btVector3 n0(0,0,0), n1(0,0,0); + btScalar a0 = 0, a1 = 0; + if (root->childs[0]) + { + calculateNormalCone(root->childs[0]); + n0 = root->childs[0]->normal; + a0 = root->childs[0]->angle; + } + if (root->childs[1]) + { + calculateNormalCone(root->childs[1]); + n1 = root->childs[1]->normal; + a1 = root->childs[1]->angle; + } + root->normal = (n0+n1).safeNormalize(); + root->angle = btMax(a0,a1) + btAngle(n0, n1)*0.5; + } +} + void btSoftBody::initializeFaceTree() { + BT_PROFILE("btSoftBody::initializeFaceTree"); m_fdbvt.clear(); + // create leaf nodes; + btAlignedObjectArray<btDbvtNode*> leafNodes; + leafNodes.resize(m_faces.size()); for (int i = 0; i < m_faces.size(); ++i) { Face& f = m_faces[i]; - f.m_leaf = m_fdbvt.insert(VolumeOf(f, 0), &f); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol = VolumeOf(f, 0); + btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode(); + node->parent = NULL; + node->data = &f; + node->childs[1] = 0; + node->volume = vol; + leafNodes[i] = node; + f.m_leaf = node; } + btAlignedObjectArray<btAlignedObjectArray<int> > adj; + adj.resize(m_faces.size()); + // construct the adjacency list for triangles + for (int i = 0; i < adj.size(); ++i) + { + for (int j = i+1; j < adj.size(); ++j) + { + int dup = 0; + for (int k = 0; k < 3; ++k) + { + for (int l = 0; l < 3; ++l) + { + if (m_faces[i].m_n[k] == m_faces[j].m_n[l]) + { + ++dup; + break; + } + } + if (dup == 2) + { + adj[i].push_back(j); + adj[j].push_back(i); + } + } + } + } + m_fdbvt.m_root = buildTreeBottomUp(leafNodes, adj); + if (m_fdbvnt) + delete m_fdbvnt; + m_fdbvnt = copyToDbvnt(m_fdbvt.m_root); + updateFaceTree(false, false); + rebuildNodeTree(); +} + +// +void btSoftBody::rebuildNodeTree() +{ + m_ndbvt.clear(); + btAlignedObjectArray<btDbvtNode*> leafNodes; + leafNodes.resize(m_nodes.size()); + for (int i = 0; i < m_nodes.size(); ++i) + { + Node& n = m_nodes[i]; + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol = btDbvtVolume::FromCR(n.m_x, 0); + btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode(); + node->parent = NULL; + node->data = &n; + node->childs[1] = 0; + node->volume = vol; + leafNodes[i] = node; + n.m_leaf = node; + } + btAlignedObjectArray<btAlignedObjectArray<int> > adj; + adj.resize(m_nodes.size()); + btAlignedObjectArray<int> old_id; + old_id.resize(m_nodes.size()); + for (int i = 0; i < m_nodes.size(); ++i) + old_id[i] = m_nodes[i].index; + for (int i = 0; i < m_nodes.size(); ++i) + m_nodes[i].index = i; + for (int i = 0; i < m_links.size(); ++i) + { + Link& l = m_links[i]; + adj[l.m_n[0]->index].push_back(l.m_n[1]->index); + adj[l.m_n[1]->index].push_back(l.m_n[0]->index); + } + m_ndbvt.m_root = buildTreeBottomUp(leafNodes, adj); + for (int i = 0; i < m_nodes.size(); ++i) + m_nodes[i].index = old_id[i]; } // @@ -2403,10 +2742,9 @@ bool btSoftBody::checkDeformableContact(const btCollisionObjectWrapper* colObjWr const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject(); // use the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg for collision detect // but resolve contact at x_n -// btTransform wtr = (predict) ? -// (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform()) -// : colObjWrap->getWorldTransform(); - const btTransform& wtr = colObjWrap->getWorldTransform(); + btTransform wtr = (predict) ? + (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform()) + : colObjWrap->getWorldTransform(); btScalar dst = m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x), @@ -2457,7 +2795,6 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO btTransform wtr = (predict) ? (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform()) : colObjWrap->getWorldTransform(); -// const btTransform& wtr = colObjWrap->getWorldTransform(); btScalar dst; //#define USE_QUADRATURE 1 @@ -2476,6 +2813,7 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO nrm, margin); nrm = wtr.getBasis() * nrm; + cti.m_colObj = colObjWrap->getCollisionObject(); // use cached contact point } else @@ -2492,10 +2830,11 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO contact_point = results.witnesses[0]; getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary); nrm = results.normal; + cti.m_colObj = colObjWrap->getCollisionObject(); for (int i = 0; i < 3; ++i) f.m_pcontact[i] = bary[i]; } - + return (dst < 0); #endif // use collision quadrature point @@ -2505,7 +2844,11 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO btVector3 local_nrm; for (int q = 0; q < m_quads.size(); ++q) { - btVector3 p = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, m_quads[q]); + btVector3 p; + if (predict) + p = BaryEval(f.m_n[0]->m_q, f.m_n[1]->m_q, f.m_n[2]->m_q, m_quads[q]); + else + p = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, m_quads[q]); btScalar local_dst = m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(p), shp, @@ -2513,43 +2856,83 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO margin); if (local_dst < dst) { + if (local_dst < 0 && predict) + return true; dst = local_dst; contact_point = p; bary = m_quads[q]; - nrm = wtr.getBasis() * local_nrm; + nrm = local_nrm; + } + if (!predict) + { + cti.m_colObj = colObjWrap->getCollisionObject(); + cti.m_normal = wtr.getBasis() * nrm; + cti.m_offset = dst; } } + return (dst < 0); } #endif +// // regular face contact +// { +// btGjkEpaSolver2::sResults results; +// btTransform triangle_transform; +// triangle_transform.setIdentity(); +// triangle_transform.setOrigin(f.m_n[0]->m_x); +// btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_x-f.m_n[0]->m_x, f.m_n[2]->m_x-f.m_n[0]->m_x); +// btVector3 guess(0,0,0); +// if (predict) +// { +// triangle_transform.setOrigin(f.m_n[0]->m_q); +// triangle = btTriangleShape(btVector3(0,0,0), f.m_n[1]->m_q-f.m_n[0]->m_q, f.m_n[2]->m_q-f.m_n[0]->m_q); +// } +// const btConvexShape* csh = static_cast<const btConvexShape*>(shp); +//// btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results); +//// dst = results.distance - margin; +//// contact_point = results.witnesses[0]; +// btGjkEpaSolver2::Penetration(&triangle, triangle_transform, csh, wtr, guess, results); +// if (results.status == btGjkEpaSolver2::sResults::Separated) +// return false; +// dst = results.distance - margin; +// contact_point = results.witnesses[1]; +// getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary); +// nrm = results.normal; +// for (int i = 0; i < 3; ++i) +// f.m_pcontact[i] = bary[i]; +// } +// +// if (!predict) +// { +// cti.m_colObj = colObjWrap->getCollisionObject(); +// cti.m_normal = nrm; +// cti.m_offset = dst; +// } +// + // regular face contact { btGjkEpaSolver2::sResults results; btTransform triangle_transform; triangle_transform.setIdentity(); - triangle_transform.setOrigin(f.m_n[0]->m_x); - btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_x-f.m_n[0]->m_x, f.m_n[2]->m_x-f.m_n[0]->m_x); + triangle_transform.setOrigin(f.m_n[0]->m_q); + btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_q-f.m_n[0]->m_q, f.m_n[2]->m_q-f.m_n[0]->m_q); btVector3 guess(0,0,0); const btConvexShape* csh = static_cast<const btConvexShape*>(shp); btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results); - dst = results.distance - margin; + dst = results.distance-csh->getMargin(); + dst -= margin; + if (dst >= 0) + return false; contact_point = results.witnesses[0]; - getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary); + getBarycentric(contact_point, f.m_n[0]->m_q, f.m_n[1]->m_q, f.m_n[2]->m_q, bary); + btVector3 curr = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary); nrm = results.normal; - for (int i = 0; i < 3; ++i) - f.m_pcontact[i] = bary[i]; - } - - if (!predict) - { cti.m_colObj = colObjWrap->getCollisionObject(); cti.m_normal = nrm; - cti.m_offset = dst; + cti.m_offset = dst + (curr - contact_point).dot(nrm); } - - if (dst < 0) - return true; - return (false); + return (dst < 0); } // @@ -3075,6 +3458,7 @@ void btSoftBody::setSpringStiffness(btScalar k) { m_links[i].Feature::m_material->m_kLST = k; } + m_repulsionStiffness = k; } void btSoftBody::initializeDmInverse() @@ -3372,18 +3756,39 @@ void btSoftBody::setMaxStress(btScalar maxStress) // void btSoftBody::interpolateRenderMesh() { - for (int i = 0; i < m_renderNodes.size(); ++i) - { - Node& n = m_renderNodes[i]; - n.m_x.setZero(); - for (int j = 0; j < 4; ++j) - { - if (m_renderNodesParents[i].size()) + if (m_z.size() > 0) + { + for (int i = 0; i < m_renderNodes.size(); ++i) + { + const Node* p0 = m_renderNodesParents[i][0]; + const Node* p1 = m_renderNodesParents[i][1]; + const Node* p2 = m_renderNodesParents[i][2]; + btVector3 normal = btCross(p1->m_x - p0->m_x, p2->m_x - p0->m_x); + btVector3 unit_normal = normal.normalized(); + Node& n = m_renderNodes[i]; + n.m_x.setZero(); + for (int j = 0; j < 3; ++j) { n.m_x += m_renderNodesParents[i][j]->m_x * m_renderNodesInterpolationWeights[i][j]; } - } - } + n.m_x += m_z[i] * unit_normal; + } + } + else + { + for (int i = 0; i < m_renderNodes.size(); ++i) + { + Node& n = m_renderNodes[i]; + n.m_x.setZero(); + for (int j = 0; j < 4; ++j) + { + if (m_renderNodesParents[i].size()) + { + n.m_x += m_renderNodesParents[i][j]->m_x * m_renderNodesInterpolationWeights[i][j]; + } + } + } + } } void btSoftBody::setCollisionQuadrature(int N) @@ -3649,13 +4054,10 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap break; case fCollision::SDF_RD: { - btRigidBody* prb1 = (btRigidBody*)btRigidBody::upcast(pcoWrap->getCollisionObject()); if (pcoWrap->getCollisionObject()->isActive() || this->isActive()) { const btTransform wtr = pcoWrap->getWorldTransform(); -// const btTransform ctr = pcoWrap->getWorldTransform(); -// const btScalar timemargin = (wtr.getOrigin() - ctr.getOrigin()).length(); const btScalar timemargin = 0; const btScalar basemargin = getCollisionShape()->getMargin(); btVector3 mins; @@ -3667,22 +4069,25 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap maxs); volume = btDbvtVolume::FromMM(mins, maxs); volume.Expand(btVector3(basemargin, basemargin, basemargin)); - btSoftColliders::CollideSDF_RD docollideNode; - docollideNode.psb = this; - docollideNode.m_colObj1Wrap = pcoWrap; - docollideNode.m_rigidBody = prb1; - docollideNode.dynmargin = basemargin + timemargin; - docollideNode.stamargin = basemargin; - m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollideNode); - - if (this->m_useFaceContact) + if (m_cfg.collisions & fCollision::SDF_RDN) + { + btSoftColliders::CollideSDF_RD docollideNode; + docollideNode.psb = this; + docollideNode.m_colObj1Wrap = pcoWrap; + docollideNode.m_rigidBody = prb1; + docollideNode.dynmargin = basemargin + timemargin; + docollideNode.stamargin = basemargin; + m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollideNode); + } + + if (((pcoWrap->getCollisionObject()->getInternalType() == CO_RIGID_BODY) && (m_cfg.collisions & fCollision::SDF_RDF)) || ((pcoWrap->getCollisionObject()->getInternalType() == CO_FEATHERSTONE_LINK) && (m_cfg.collisions & fCollision::SDF_MDF))) { btSoftColliders::CollideSDF_RDF docollideFace; docollideFace.psb = this; docollideFace.m_colObj1Wrap = pcoWrap; docollideFace.m_rigidBody = prb1; - docollideFace.dynmargin = basemargin + timemargin; - docollideFace.stamargin = basemargin; + docollideFace.dynmargin = basemargin + timemargin; + docollideFace.stamargin = basemargin; m_fdbvt.collideTV(m_fdbvt.m_root, volume, docollideFace); } } @@ -3691,51 +4096,6 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap } } -static inline btDbvntNode* copyToDbvnt(const btDbvtNode* n) -{ - if (n == 0) - return 0; - btDbvntNode* root = new btDbvntNode(n); - if (n->isinternal()) - { - btDbvntNode* c0 = copyToDbvnt(n->childs[0]); - root->childs[0] = c0; - btDbvntNode* c1 = copyToDbvnt(n->childs[1]); - root->childs[1] = c1; - } - return root; -} - -static inline void calculateNormalCone(btDbvntNode* root) -{ - if (!root) - return; - if (root->isleaf()) - { - const btSoftBody::Face* face = (btSoftBody::Face*)root->data; - root->normal = face->m_normal; - root->angle = 0; - } - else - { - btVector3 n0(0,0,0), n1(0,0,0); - btScalar a0 = 0, a1 = 0; - if (root->childs[0]) - { - calculateNormalCone(root->childs[0]); - n0 = root->childs[0]->normal; - a0 = root->childs[0]->angle; - } - if (root->childs[1]) - { - calculateNormalCone(root->childs[1]); - n1 = root->childs[1]->normal; - a1 = root->childs[1]->angle; - } - root->normal = (n0+n1).safeNormalize(); - root->angle = btMax(a0,a1) + btAngle(n0, n1)*0.5; - } -} // void btSoftBody::defaultCollisionHandler(btSoftBody* psb) { @@ -3779,6 +4139,8 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb) break; case fCollision::VF_DD: { + if (!psb->m_softSoftCollision) + return; if (psb->isActive() || this->isActive()) { if (this != psb) @@ -3797,6 +4159,7 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb) docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root, docollide.psb[1]->m_fdbvt.m_root, docollide); + /* psb1 nodes vs psb0 faces */ if (this->m_tetras.size() > 0) docollide.useFaceNormal = true; @@ -3812,20 +4175,17 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb) { if (psb->useSelfCollision()) { - btSoftColliders::CollideFF_DD docollide; - docollide.mrg = getCollisionShape()->getMargin() + - psb->getCollisionShape()->getMargin(); - docollide.psb[0] = this; - docollide.psb[1] = psb; - if (this->m_tetras.size() > 0) - docollide.useFaceNormal = true; - else - docollide.useFaceNormal = false; - /* psb0 faces vs psb0 faces */ - btDbvntNode* root = copyToDbvnt(this->m_fdbvt.m_root); - calculateNormalCone(root); - this->m_fdbvt.selfCollideT(root,docollide); - delete root; + btSoftColliders::CollideFF_DD docollide; + docollide.mrg = 2*getCollisionShape()->getMargin(); + docollide.psb[0] = this; + docollide.psb[1] = psb; + if (this->m_tetras.size() > 0) + docollide.useFaceNormal = true; + else + docollide.useFaceNormal = false; + /* psb0 faces vs psb0 faces */ + calculateNormalCone(this->m_fdbvnt); + this->m_fdbvt.selfCollideT(m_fdbvnt,docollide); } } } @@ -3837,6 +4197,58 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb) } } +void btSoftBody::geometricCollisionHandler(btSoftBody* psb) +{ + if (psb->isActive() || this->isActive()) + { + if (this != psb) + { + btSoftColliders::CollideCCD docollide; + /* common */ + docollide.mrg = SAFE_EPSILON; // for rounding error instead of actual margin + docollide.dt = psb->m_sst.sdt; + /* psb0 nodes vs psb1 faces */ + if (psb->m_tetras.size() > 0) + docollide.useFaceNormal = true; + else + docollide.useFaceNormal = false; + docollide.psb[0] = this; + docollide.psb[1] = psb; + docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); + /* psb1 nodes vs psb0 faces */ + if (this->m_tetras.size() > 0) + docollide.useFaceNormal = true; + else + docollide.useFaceNormal = false; + docollide.psb[0] = psb; + docollide.psb[1] = this; + docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); + } + else + { + if (psb->useSelfCollision()) + { + btSoftColliders::CollideCCD docollide; + docollide.mrg = SAFE_EPSILON; + docollide.psb[0] = this; + docollide.psb[1] = psb; + docollide.dt = psb->m_sst.sdt; + if (this->m_tetras.size() > 0) + docollide.useFaceNormal = true; + else + docollide.useFaceNormal = false; + /* psb0 faces vs psb0 faces */ + calculateNormalCone(this->m_fdbvnt); // should compute this outside of this scope + this->m_fdbvt.selfCollideT(m_fdbvnt,docollide); + } + } + } +} + void btSoftBody::setWindVelocity(const btVector3& velocity) { m_windVelocity = velocity; diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.h b/thirdparty/bullet/BulletSoftBody/btSoftBody.h index 2b048c1118..6a55eccbd2 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBody.h +++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.h @@ -35,6 +35,8 @@ subject to the following restrictions: //#else #define btSoftBodyData btSoftBodyFloatData #define btSoftBodyDataName "btSoftBodyFloatData" +static const btScalar OVERLAP_REDUCTION_FACTOR = 0.1; +static unsigned long seed = 243703; //#endif //BT_USE_DOUBLE_PRECISION class btBroadphaseInterface; @@ -161,14 +163,18 @@ public: RVSmask = 0x000f, ///Rigid versus soft mask SDF_RS = 0x0001, ///SDF based rigid vs soft CL_RS = 0x0002, ///Cluster vs convex rigid vs soft - SDF_RD = 0x0003, ///DF based rigid vs deformable - SDF_RDF = 0x0004, ///DF based rigid vs deformable faces + SDF_RD = 0x0004, ///rigid vs deformable - SVSmask = 0x00F0, ///Rigid versus soft mask + SVSmask = 0x00f0, ///Rigid versus soft mask VF_SS = 0x0010, ///Vertex vs face soft vs soft handling CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling CL_SELF = 0x0040, ///Cluster soft body self collision - VF_DD = 0x0050, ///Vertex vs face soft vs soft handling + VF_DD = 0x0080, ///Vertex vs face soft vs soft handling + + RVDFmask = 0x0f00, /// Rigid versus deformable face mask + SDF_RDF = 0x0100, /// GJK based Rigid vs. deformable face + SDF_MDF = 0x0200, /// GJK based Multibody vs. deformable face + SDF_RDN = 0x0400, /// SDF based Rigid vs. deformable node /* presets */ Default = SDF_RS, END @@ -257,13 +263,13 @@ public: btVector3 m_x; // Position btVector3 m_q; // Previous step position/Test position btVector3 m_v; // Velocity - btVector3 m_vsplit; // Temporary Velocity in addintion to velocity used in split impulse btVector3 m_vn; // Previous step velocity btVector3 m_f; // Force accumulator btVector3 m_n; // Normal btScalar m_im; // 1/mass btScalar m_area; // Area btDbvtNode* m_leaf; // Leaf data + btScalar m_penetration; // depth of penetration int m_battach : 1; // Attached int index; }; @@ -289,6 +295,7 @@ public: btScalar m_ra; // Rest area btDbvtNode* m_leaf; // Leaf data btVector4 m_pcontact; // barycentric weights of the persistent contact + btVector3 m_n0, m_n1, m_vn; int m_index; }; /* Tetra */ @@ -717,6 +724,15 @@ public: /* SolverState */ struct SolverState { + //if you add new variables, always initialize them! + SolverState() + :sdt(0), + isdt(0), + velmrg(0), + radmrg(0), + updmrg(0) + { + } btScalar sdt; // dt*timescale btScalar isdt; // 1/sdt btScalar velmrg; // velocity margin @@ -796,22 +812,24 @@ public: bool m_bUpdateRtCst; // Update runtime constants btDbvt m_ndbvt; // Nodes tree btDbvt m_fdbvt; // Faces tree + btDbvntNode* m_fdbvnt; // Faces tree with normals btDbvt m_cdbvt; // Clusters tree tClusterArray m_clusters; // Clusters - btScalar m_dampingCoefficient; // Damping Coefficient - btScalar m_sleepingThreshold; - btScalar m_maxSpeedSquared; - bool m_useFaceContact; - btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection - - btAlignedObjectArray<btVector4> m_renderNodesInterpolationWeights; - btAlignedObjectArray<btAlignedObjectArray<const btSoftBody::Node*> > m_renderNodesParents; - bool m_useSelfCollision; + btScalar m_dampingCoefficient; // Damping Coefficient + btScalar m_sleepingThreshold; + btScalar m_maxSpeedSquared; + btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection + btScalar m_repulsionStiffness; + btAlignedObjectArray<btVector3> m_X; // initial positions + + btAlignedObjectArray<btVector4> m_renderNodesInterpolationWeights; + btAlignedObjectArray<btAlignedObjectArray<const btSoftBody::Node*> > m_renderNodesParents; + btAlignedObjectArray<btScalar> m_z; // vertical distance used in extrapolation + bool m_useSelfCollision; + bool m_softSoftCollision; btAlignedObjectArray<bool> m_clusterConnectivity; //cluster connectivity, for self-collision - btTransform m_initialWorldTransform; - btVector3 m_windVelocity; btScalar m_restLengthScale; @@ -843,11 +861,6 @@ public: { m_dampingCoefficient = damping_coeff; } - - void setUseFaceContact(bool useFaceContact) - { - m_useFaceContact = false; - } ///@todo: avoid internal softbody shape hack and move collision code to collision library virtual void setCollisionShape(btCollisionShape* collisionShape) @@ -957,6 +970,16 @@ public: void setVolumeMass(btScalar mass); /* Set volume density (using tetrahedrons) */ void setVolumeDensity(btScalar density); + /* Get the linear velocity of the center of mass */ + btVector3 getLinearVelocity(); + /* Set the linear velocity of the center of mass */ + void setLinearVelocity(const btVector3& linVel); + /* Set the angular velocity of the center of mass */ + void setAngularVelocity(const btVector3& angVel); + /* Get best fit rigid transform */ + btTransform getRigidTransform(); + /* Transform to given pose */ + void transformTo(const btTransform& trs); /* Transform */ void transform(const btTransform& trs); /* Translate */ @@ -1023,6 +1046,11 @@ public: bool rayTest(const btVector3& rayFrom, const btVector3& rayTo, sRayCast& results); + bool rayFaceTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results); + int rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo, + btScalar& mint, int& index) const; /* Solver presets */ void setSolver(eSolverPresets::_ preset); /* predictMotion */ @@ -1120,6 +1148,7 @@ public: int rayTest(const btVector3& rayFrom, const btVector3& rayTo, btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const; void initializeFaceTree(); + void rebuildNodeTree(); btVector3 evaluateCom() const; bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, Face& f, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; @@ -1152,7 +1181,180 @@ public: static void VSolve_Links(btSoftBody* psb, btScalar kst); static psolver_t getSolver(ePSolver::_ solver); static vsolver_t getSolver(eVSolver::_ solver); + void geometricCollisionHandler(btSoftBody* psb); +#define SAFE_EPSILON SIMD_EPSILON*100.0 + void updateNode(btDbvtNode* node, bool use_velocity, bool margin) + { + if (node->isleaf()) + { + btSoftBody::Node* n = (btSoftBody::Node*)(node->data); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision + if (use_velocity) + { + btVector3 points[2] = {n->m_x, n->m_x + m_sst.sdt * n->m_v}; + vol = btDbvtVolume::FromPoints(points, 2); + vol.Expand(btVector3(pad, pad, pad)); + } + else + { + vol = btDbvtVolume::FromCR(n->m_x, pad); + } + node->volume = vol; + return; + } + else + { + updateNode(node->childs[0], use_velocity, margin); + updateNode(node->childs[1], use_velocity, margin); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + Merge(node->childs[0]->volume, node->childs[1]->volume, vol); + node->volume = vol; + } + } + + void updateNodeTree(bool use_velocity, bool margin) + { + if (m_ndbvt.m_root) + updateNode(m_ndbvt.m_root, use_velocity, margin); + } + + template <class DBVTNODE> // btDbvtNode or btDbvntNode + void updateFace(DBVTNODE* node, bool use_velocity, bool margin) + { + if (node->isleaf()) + { + btSoftBody::Face* f = (btSoftBody::Face*)(node->data); + btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + if (use_velocity) + { + btVector3 points[6] = {f->m_n[0]->m_x, f->m_n[0]->m_x + m_sst.sdt * f->m_n[0]->m_v, + f->m_n[1]->m_x, f->m_n[1]->m_x + m_sst.sdt * f->m_n[1]->m_v, + f->m_n[2]->m_x, f->m_n[2]->m_x + m_sst.sdt * f->m_n[2]->m_v}; + vol = btDbvtVolume::FromPoints(points, 6); + } + else + { + btVector3 points[3] = {f->m_n[0]->m_x, + f->m_n[1]->m_x, + f->m_n[2]->m_x}; + vol = btDbvtVolume::FromPoints(points, 3); + } + vol.Expand(btVector3(pad, pad, pad)); + node->volume = vol; + return; + } + else + { + updateFace(node->childs[0], use_velocity, margin); + updateFace(node->childs[1], use_velocity, margin); + ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; + Merge(node->childs[0]->volume, node->childs[1]->volume, vol); + node->volume = vol; + } + } + void updateFaceTree(bool use_velocity, bool margin) + { + if (m_fdbvt.m_root) + updateFace(m_fdbvt.m_root, use_velocity, margin); + if (m_fdbvnt) + updateFace(m_fdbvnt, use_velocity, margin); + } + + template <typename T> + static inline T BaryEval(const T& a, + const T& b, + const T& c, + const btVector3& coord) + { + return (a * coord.x() + b * coord.y() + c * coord.z()); + } + void applyRepulsionForce(btScalar timeStep, bool applySpringForce) + { + btAlignedObjectArray<int> indices; + { + // randomize the order of repulsive force + indices.resize(m_faceNodeContacts.size()); + for (int i = 0; i < m_faceNodeContacts.size(); ++i) + indices[i] = i; +#define NEXTRAND (seed = (1664525L * seed + 1013904223L) & 0xffffffff) + int i, ni; + + for (i = 0, ni = indices.size(); i < ni; ++i) + { + btSwap(indices[i], indices[NEXTRAND % ni]); + } + } + for (int k = 0; k < m_faceNodeContacts.size(); ++k) + { + int i = indices[k]; + btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i]; + btSoftBody::Node* node = c.m_node; + btSoftBody::Face* face = c.m_face; + const btVector3& w = c.m_bary; + const btVector3& n = c.m_normal; + btVector3 l = node->m_x - BaryEval(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, w); + btScalar d = c.m_margin - n.dot(l); + d = btMax(btScalar(0),d); + + const btVector3& va = node->m_v; + btVector3 vb = BaryEval(face->m_n[0]->m_v, face->m_n[1]->m_v, face->m_n[2]->m_v, w); + btVector3 vr = va - vb; + const btScalar vn = btDot(vr, n); // dn < 0 <==> opposing + if (vn > OVERLAP_REDUCTION_FACTOR * d / timeStep) + continue; + btVector3 vt = vr - vn*n; + btScalar I = 0; + btScalar mass = node->m_im == 0 ? 0 : btScalar(1)/node->m_im; + if (applySpringForce) + I = -btMin(m_repulsionStiffness * timeStep * d, mass * (OVERLAP_REDUCTION_FACTOR * d / timeStep - vn)); + if (vn < 0) + I += 0.5 * mass * vn; + btScalar face_penetration = 0, node_penetration = node->m_penetration; + for (int i = 0; i < 3; ++i) + face_penetration = btMax(face_penetration, face->m_n[i]->m_penetration); + btScalar I_tilde = .5 *I /(1.0+w.length2()); + +// double the impulse if node or face is constrained. + if (face_penetration > 0 || node_penetration > 0) + I_tilde *= 2.0; + if (face_penetration <= node_penetration) + { + for (int j = 0; j < 3; ++j) + face->m_n[j]->m_v += w[j]*n*I_tilde*node->m_im; + } + if (face_penetration >= node_penetration) + { + node->m_v -= I_tilde*node->m_im*n; + } + + // apply frictional impulse + btScalar vt_norm = vt.safeNorm(); + if (vt_norm > SIMD_EPSILON) + { + btScalar delta_vn = -2 * I * node->m_im; + btScalar mu = c.m_friction; + btScalar vt_new = btMax(btScalar(1) - mu * delta_vn / (vt_norm + SIMD_EPSILON), btScalar(0))*vt_norm; + I = 0.5 * mass * (vt_norm-vt_new); + vt.safeNormalize(); + I_tilde = .5 *I /(1.0+w.length2()); +// double the impulse if node or face is constrained. +// if (face_penetration > 0 || node_penetration > 0) +// I_tilde *= 2.0; + if (face_penetration <= node_penetration) + { + for (int j = 0; j < 3; ++j) + face->m_n[j]->m_v += w[j] * vt * I_tilde * (face->m_n[j])->m_im; + } + if (face_penetration >= node_penetration) + { + node->m_v -= I_tilde * node->m_im * vt; + } + } + } + } virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp index 649d6f58cf..c1a87c7d57 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp +++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp @@ -1300,13 +1300,23 @@ btSoftBody* btSoftBodyHelpers::CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, } else if (reading_tets) { + int d; + ss >> d; + if (d != 4) + { + printf("Load deformable failed: Only Tetrahedra are supported in VTK file.\n"); + fs.close(); + return 0; + } ss.ignore(128, ' '); // ignore "4" Index tet; tet.resize(4); for (size_t i = 0; i < 4; i++) { ss >> tet[i]; + printf("%d ", tet[i]); } + printf("\n"); indices[indices_count++] = tet; } } @@ -1500,10 +1510,27 @@ void btSoftBodyHelpers::getBarycentricWeights(const btVector3& a, const btVector bary = btVector4(va6*v6, vb6*v6, vc6*v6, vd6*v6); } +// Given a simplex with vertices a,b,c, find the barycentric weights of p in this simplex. bary[3] = 0. +void btSoftBodyHelpers::getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& p, btVector4& bary) +{ + btVector3 v0 = b - a, v1 = c - a, v2 = p - a; + btScalar d00 = btDot(v0, v0); + btScalar d01 = btDot(v0, v1); + btScalar d11 = btDot(v1, v1); + btScalar d20 = btDot(v2, v0); + btScalar d21 = btDot(v2, v1); + btScalar invDenom = 1.0 / (d00 * d11 - d01 * d01); + bary[1] = (d11 * d20 - d01 * d21) * invDenom; + bary[2] = (d00 * d21 - d01 * d20) * invDenom; + bary[0] = 1.0 - bary[1] - bary[2]; + bary[3] = 0; +} + // Iterate through all render nodes to find the simulation tetrahedron that contains the render node and record the barycentric weights // If the node is not inside any tetrahedron, assign it to the tetrahedron in which the node has the least negative barycentric weight void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb) { + psb->m_z.resize(0); psb->m_renderNodesInterpolationWeights.resize(psb->m_renderNodes.size()); psb->m_renderNodesParents.resize(psb->m_renderNodes.size()); for (int i = 0; i < psb->m_renderNodes.size(); ++i) @@ -1513,7 +1540,6 @@ void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb) btVector4 optimal_bary; btScalar min_bary_weight = -1e3; btAlignedObjectArray<const btSoftBody::Node*> optimal_parents; - bool found = false; for (int j = 0; j < psb->m_tetras.size(); ++j) { const btSoftBody::Tetra& t = psb->m_tetras[j]; @@ -1544,3 +1570,55 @@ void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb) psb->m_renderNodesParents[i] = optimal_parents; } } + + +// Iterate through all render nodes to find the simulation triangle that's closest to the node in the barycentric sense. +void btSoftBodyHelpers::extrapolateBarycentricWeights(btSoftBody* psb) +{ + psb->m_renderNodesInterpolationWeights.resize(psb->m_renderNodes.size()); + psb->m_renderNodesParents.resize(psb->m_renderNodes.size()); + psb->m_z.resize(psb->m_renderNodes.size()); + for (int i = 0; i < psb->m_renderNodes.size(); ++i) + { + const btVector3& p = psb->m_renderNodes[i].m_x; + btVector4 bary; + btVector4 optimal_bary; + btScalar min_bary_weight = -SIMD_INFINITY; + btAlignedObjectArray<const btSoftBody::Node*> optimal_parents; + btScalar dist = 0, optimal_dist = 0; + for (int j = 0; j < psb->m_faces.size(); ++j) + { + const btSoftBody::Face& f = psb->m_faces[j]; + btVector3 n = btCross(f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x); + btVector3 unit_n = n.normalized(); + dist = (p-f.m_n[0]->m_x).dot(unit_n); + btVector3 proj_p = p - dist*unit_n; + getBarycentricWeights(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, proj_p, bary); + btScalar new_min_bary_weight = bary[0]; + for (int k = 1; k < 3; ++k) + { + new_min_bary_weight = btMin(new_min_bary_weight, bary[k]); + } + + // p is out of the current best triangle, we found a traingle that's better + bool better_than_closest_outisde = (new_min_bary_weight > min_bary_weight && min_bary_weight<0.); + // p is inside of the current best triangle, we found a triangle that's better + bool better_than_best_inside = (new_min_bary_weight>=0 && min_bary_weight>=0 && btFabs(dist)<btFabs(optimal_dist)); + + if (better_than_closest_outisde || better_than_best_inside) + { + btAlignedObjectArray<const btSoftBody::Node*> parents; + parents.push_back(f.m_n[0]); + parents.push_back(f.m_n[1]); + parents.push_back(f.m_n[2]); + optimal_parents = parents; + optimal_bary = bary; + optimal_dist = dist; + min_bary_weight = new_min_bary_weight; + } + } + psb->m_renderNodesInterpolationWeights[i] = optimal_bary; + psb->m_renderNodesParents[i] = optimal_parents; + psb->m_z[i] = optimal_dist; + } +} diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h index b20f2f6d62..abe1870890 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h +++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h @@ -148,8 +148,12 @@ struct btSoftBodyHelpers static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, const btVector3& p, btVector4& bary); + static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& p, btVector4& bary); + static void interpolateBarycentricWeights(btSoftBody* psb); + static void extrapolateBarycentricWeights(btSoftBody* psb); + static void generateBoundaryFaces(btSoftBody* psb); static void duplicateFaces(const char* filename, const btSoftBody* psb); diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h b/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h index cde4746d58..b9ebc95b6b 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h +++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h @@ -18,7 +18,6 @@ subject to the following restrictions: #define _BT_SOFT_BODY_INTERNALS_H #include "btSoftBody.h" - #include "LinearMath/btQuickprof.h" #include "LinearMath/btPolarDecomposition.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" @@ -29,9 +28,10 @@ subject to the following restrictions: #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include <string.h> //for memset #include <cmath> +#include "poly34.h" // Given a multibody link, a contact point and a contact direction, fill in the jacobian data needed to calculate the velocity change given an impulse in the contact direction -static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, +static SIMD_FORCE_INLINE void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, const btVector3& dir) @@ -44,7 +44,7 @@ static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v); } -static btVector3 generateUnitOrthogonalVector(const btVector3& u) +static SIMD_FORCE_INLINE btVector3 generateUnitOrthogonalVector(const btVector3& u) { btScalar ux = u.getX(); btScalar uy = u.getY(); @@ -62,6 +62,571 @@ static btVector3 generateUnitOrthogonalVector(const btVector3& u) v.normalize(); return v; } + +static SIMD_FORCE_INLINE bool proximityTest(const btVector3& x1, const btVector3& x2, const btVector3& x3, const btVector3& x4, const btVector3& normal, const btScalar& mrg, btVector3& bary) +{ + btVector3 x43 = x4-x3; + if (std::abs(x43.dot(normal)) > mrg) + return false; + btVector3 x13 = x1-x3; + btVector3 x23 = x2-x3; + btScalar a11 = x13.length2(); + btScalar a22 = x23.length2(); + btScalar a12 = x13.dot(x23); + btScalar b1 = x13.dot(x43); + btScalar b2 = x23.dot(x43); + btScalar det = a11*a22 - a12*a12; + if (det < SIMD_EPSILON) + return false; + btScalar w1 = (b1*a22-b2*a12)/det; + btScalar w2 = (b2*a11-b1*a12)/det; + btScalar w3 = 1-w1-w2; + btScalar delta = mrg / std::sqrt(0.5*std::abs(x13.cross(x23).safeNorm())); + bary = btVector3(w1,w2,w3); + for (int i = 0; i < 3; ++i) + { + if (bary[i] < -delta || bary[i] > 1+delta) + return false; + } + return true; +} +static const int KDOP_COUNT = 13; +static btVector3 dop[KDOP_COUNT]={btVector3(1,0,0), + btVector3(0,1,0), + btVector3(0,0,1), + btVector3(1,1,0), + btVector3(1,0,1), + btVector3(0,1,1), + btVector3(1,-1,0), + btVector3(1,0,-1), + btVector3(0,1,-1), + btVector3(1,1,1), + btVector3(1,-1,1), + btVector3(1,1,-1), + btVector3(1,-1,-1) +}; + +static inline int getSign(const btVector3& n, const btVector3& x) +{ + btScalar d = n.dot(x); + if (d>SIMD_EPSILON) + return 1; + if (d<-SIMD_EPSILON) + return -1; + return 0; +} + +static SIMD_FORCE_INLINE bool hasSeparatingPlane(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt) +{ + btVector3 hex[6] = {face->m_n[0]->m_x - node->m_x, + face->m_n[1]->m_x - node->m_x, + face->m_n[2]->m_x - node->m_x, + face->m_n[0]->m_x + dt*face->m_n[0]->m_v - node->m_x, + face->m_n[1]->m_x + dt*face->m_n[1]->m_v - node->m_x, + face->m_n[2]->m_x + dt*face->m_n[2]->m_v - node->m_x + }; + btVector3 segment = dt*node->m_v; + for (int i = 0; i < KDOP_COUNT; ++i) + { + int s = getSign(dop[i], segment); + int j = 0; + for (; j < 6; ++j) + { + if (getSign(dop[i], hex[j]) == s) + break; + } + if (j == 6) + return true; + } + return false; +} + +static SIMD_FORCE_INLINE bool nearZero(const btScalar& a) +{ + return (a>-SAFE_EPSILON && a<SAFE_EPSILON); +} +static SIMD_FORCE_INLINE bool sameSign(const btScalar& a, const btScalar& b) +{ + return (nearZero(a) || nearZero(b) || (a>SAFE_EPSILON && b>SAFE_EPSILON) || (a<-SAFE_EPSILON && b<-SAFE_EPSILON)); +} +static SIMD_FORCE_INLINE bool diffSign(const btScalar& a, const btScalar& b) +{ + return !sameSign(a, b); +} +inline btScalar evaluateBezier2(const btScalar &p0, const btScalar &p1, const btScalar &p2, const btScalar &t, const btScalar &s) +{ + btScalar s2 = s*s; + btScalar t2 = t*t; + + return p0*s2+p1*btScalar(2.0)*s*t+p2*t2; +} +inline btScalar evaluateBezier(const btScalar &p0, const btScalar &p1, const btScalar &p2, const btScalar &p3, const btScalar &t, const btScalar &s) +{ + btScalar s2 = s*s; + btScalar s3 = s2*s; + btScalar t2 = t*t; + btScalar t3 = t2*t; + + return p0*s3+p1*btScalar(3.0)*s2*t+p2*btScalar(3.0)*s*t2+p3*t3; +} +static SIMD_FORCE_INLINE bool getSigns(bool type_c, const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& t0, const btScalar& t1, btScalar <0, btScalar <1) +{ + if (sameSign(t0, t1)) { + lt0 = t0; + lt1 = t0; + return true; + } + + if (type_c || diffSign(k0, k3)) { + btScalar ft = evaluateBezier(k0, k1, k2, k3, t0, -t1); + if (t0<-0) + ft = -ft; + + if (sameSign(ft, k0)) { + lt0 = t1; + lt1 = t1; + } + else { + lt0 = t0; + lt1 = t0; + } + return true; + } + + if (!type_c) { + btScalar ft = evaluateBezier(k0, k1, k2, k3, t0, -t1); + if (t0<-0) + ft = -ft; + + if (diffSign(ft, k0)) { + lt0 = t0; + lt1 = t1; + return true; + } + + btScalar fk = evaluateBezier2(k1-k0, k2-k1, k3-k2, t0, -t1); + + if (sameSign(fk, k1-k0)) + lt0 = lt1 = t1; + else + lt0 = lt1 = t0; + + return true; + } + return false; +} + +static SIMD_FORCE_INLINE void getBernsteinCoeff(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, btScalar& k0, btScalar& k1, btScalar& k2, btScalar& k3) +{ + const btVector3& n0 = face->m_n0; + const btVector3& n1 = face->m_n1; + btVector3 n_hat = n0 + n1 - face->m_vn; + btVector3 p0ma0 = node->m_x - face->m_n[0]->m_x; + btVector3 p1ma1 = node->m_q - face->m_n[0]->m_q; + k0 = (p0ma0).dot(n0) * 3.0; + k1 = (p0ma0).dot(n_hat) + (p1ma1).dot(n0); + k2 = (p1ma1).dot(n_hat) + (p0ma0).dot(n1); + k3 = (p1ma1).dot(n1) * 3.0; +} + +static SIMD_FORCE_INLINE void polyDecomposition(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& j0, const btScalar& j1, const btScalar& j2, btScalar& u0, btScalar& u1, btScalar& v0, btScalar& v1) +{ + btScalar denom = 4.0 * (j1-j2) * (j1-j0) + (j2-j0) * (j2-j0); + u0 = (2.0*(j1-j2)*(3.0*k1-2.0*k0-k3) - (j0-j2)*(3.0*k2-2.0*k3-k0)) / denom; + u1 = (2.0*(j1-j0)*(3.0*k2-2.0*k3-k0) - (j2-j0)*(3.0*k1-2.0*k0-k3)) / denom; + v0 = k0-u0*j0; + v1 = k3-u1*j2; +} + +static SIMD_FORCE_INLINE bool rootFindingLemma(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3) +{ + btScalar u0, u1, v0, v1; + btScalar j0 = 3.0*(k1-k0); + btScalar j1 = 3.0*(k2-k1); + btScalar j2 = 3.0*(k3-k2); + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (sameSign(v0, v1)) + { + btScalar Ypa = j0*(1.0-v0)*(1.0-v0) + 2.0*j1*v0*(1.0-v0) + j2*v0*v0; // Y'(v0) + if (sameSign(Ypa, j0)) + { + return (diffSign(k0,v1)); + } + } + return diffSign(k0,v0); +} + +static SIMD_FORCE_INLINE void getJs(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Node* a, const btSoftBody::Node* b, const btSoftBody::Node* c, const btSoftBody::Node* p, const btScalar& dt, btScalar& j0, btScalar& j1, btScalar& j2) +{ + const btVector3& a0 = a->m_x; + const btVector3& b0 = b->m_x; + const btVector3& c0 = c->m_x; + const btVector3& va = a->m_v; + const btVector3& vb = b->m_v; + const btVector3& vc = c->m_v; + const btVector3 a1 = a0 + dt*va; + const btVector3 b1 = b0 + dt*vb; + const btVector3 c1 = c0 + dt*vc; + btVector3 n0 = (b0-a0).cross(c0-a0); + btVector3 n1 = (b1-a1).cross(c1-a1); + btVector3 n_hat = n0+n1 - dt*dt*(vb-va).cross(vc-va); + const btVector3& p0 = p->m_x; + const btVector3& vp = p->m_v; + btVector3 p1 = p0 + dt*vp; + btVector3 m0 = (b0-p0).cross(c0-p0); + btVector3 m1 = (b1-p1).cross(c1-p1); + btVector3 m_hat = m0+m1 - dt*dt*(vb-vp).cross(vc-vp); + btScalar l0 = m0.dot(n0); + btScalar l1 = 0.25 * (m0.dot(n_hat) + m_hat.dot(n0)); + btScalar l2 = btScalar(1)/btScalar(6)*(m0.dot(n1) + m_hat.dot(n_hat) + m1.dot(n0)); + btScalar l3 = 0.25 * (m_hat.dot(n1) + m1.dot(n_hat)); + btScalar l4 = m1.dot(n1); + + btScalar k1p = 0.25 * k0 + 0.75 * k1; + btScalar k2p = 0.5 * k1 + 0.5 * k2; + btScalar k3p = 0.75 * k2 + 0.25 * k3; + + btScalar s0 = (l1 * k0 - l0 * k1p)*4.0; + btScalar s1 = (l2 * k0 - l0 * k2p)*2.0; + btScalar s2 = (l3 * k0 - l0 * k3p)*btScalar(4)/btScalar(3); + btScalar s3 = l4 * k0 - l0 * k3; + + j0 = (s1*k0 - s0*k1) * 3.0; + j1 = (s2*k0 - s0*k2) * 1.5; + j2 = (s3*k0 - s0*k3); +} + +static SIMD_FORCE_INLINE bool signDetermination1Internal(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& u0, const btScalar& u1, const btScalar& v0, const btScalar& v1) +{ + btScalar Yu0 = k0*(1.0-u0)*(1.0-u0)*(1.0-u0) + 3.0*k1*u0*(1.0-u0)*(1.0-u0) + 3.0*k2*u0*u0*(1.0-u0) + k3*u0*u0*u0; // Y(u0) + btScalar Yv0 = k0*(1.0-v0)*(1.0-v0)*(1.0-v0) + 3.0*k1*v0*(1.0-v0)*(1.0-v0) + 3.0*k2*v0*v0*(1.0-v0) + k3*v0*v0*v0; // Y(v0) + + btScalar sign_Ytp = (u0 > u1) ? Yu0 : -Yu0; + btScalar L = sameSign(sign_Ytp, k0) ? u1 : u0; + sign_Ytp = (v0 > v1) ? Yv0 : -Yv0; + btScalar K = (sameSign(sign_Ytp,k0)) ? v1 : v0; + return diffSign(L,K); +} + +static SIMD_FORCE_INLINE bool signDetermination2Internal(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& j0, const btScalar& j1, const btScalar& j2, const btScalar& u0, const btScalar& u1, const btScalar& v0, const btScalar& v1) +{ + btScalar Yu0 = k0*(1.0-u0)*(1.0-u0)*(1.0-u0) + 3.0*k1*u0*(1.0-u0)*(1.0-u0) + 3.0*k2*u0*u0*(1.0-u0) + k3*u0*u0*u0; // Y(u0) + btScalar sign_Ytp = (u0 > u1) ? Yu0 : -Yu0, L1, L2; + if (diffSign(sign_Ytp,k0)) + { + L1 = u0; + L2 = u1; + } + else + { + btScalar Yp_u0 = j0*(1.0-u0)*(1.0-u0) + 2.0*j1*(1.0-u0)*u0 + j2*u0*u0; + if (sameSign(Yp_u0,j0)) + { + L1 = u1; + L2 = u1; + } + else + { + L1 = u0; + L2 = u0; + } + } + btScalar Yv0 = k0*(1.0-v0)*(1.0-v0)*(1.0-v0) + 3.0*k1*v0*(1.0-v0)*(1.0-v0) + 3.0*k2*v0*v0*(1.0-v0) + k3*v0*v0*v0; // Y(uv0) + sign_Ytp = (v0 > v1) ? Yv0 : -Yv0; + btScalar K1, K2; + if (diffSign(sign_Ytp,k0)) + { + K1 = v0; + K2 = v1; + } + else + { + btScalar Yp_v0 = j0*(1.0-v0)*(1.0-v0) + 2.0*j1*(1.0-v0)*v0 + j2*v0*v0; + if (sameSign(Yp_v0,j0)) + { + K1 = v1; + K2 = v1; + } + else + { + K1 = v0; + K2 = v0; + } + } + return (diffSign(K1, L1) || diffSign(L2, K2)); +} + +static SIMD_FORCE_INLINE bool signDetermination1(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt) +{ + btScalar j0, j1, j2, u0, u1, v0, v1; + // p1 + getJs(k0,k1,k2,k3,face->m_n[0], face->m_n[1], face->m_n[2], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1)) + return false; + } + // p2 + getJs(k0,k1,k2,k3,face->m_n[1], face->m_n[2], face->m_n[0], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1)) + return false; + } + // p3 + getJs(k0,k1,k2,k3,face->m_n[2], face->m_n[0], face->m_n[1], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1)) + return false; + } + return true; +} + +static SIMD_FORCE_INLINE bool signDetermination2(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt) +{ + btScalar j0, j1, j2, u0, u1, v0, v1; + // p1 + getJs(k0,k1,k2,k3,face->m_n[0], face->m_n[1], face->m_n[2], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + bool bt0 = true, bt1=true; + getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + bt0 = false; + if (lt1 < -SAFE_EPSILON) + bt1 = false; + if (!bt0 && !bt1) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1)) + return false; + } + // p2 + getJs(k0,k1,k2,k3,face->m_n[1], face->m_n[2], face->m_n[0], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + bool bt0=true, bt1=true; + getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + bt0 = false; + if (lt1 < -SAFE_EPSILON) + bt1 = false; + if (!bt0 && !bt1) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1)) + return false; + } + // p3 + getJs(k0,k1,k2,k3,face->m_n[2], face->m_n[0], face->m_n[1], node, dt, j0, j1, j2); + if (nearZero(j0+j2-j1*2.0)) + { + btScalar lt0, lt1; + bool bt0=true, bt1=true; + getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1); + if (lt0 < -SAFE_EPSILON) + bt0 = false; + if (lt1 < -SAFE_EPSILON) + bt1 = false; + if (!bt0 && !bt1) + return false; + } + else + { + polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1); + if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1)) + return false; + } + return true; +} + +static SIMD_FORCE_INLINE bool coplanarAndInsideTest(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt) +{ + // Coplanar test + if (diffSign(k1-k0, k3-k2)) + { + // Case b: + if (sameSign(k0, k3) && !rootFindingLemma(k0,k1,k2,k3)) + return false; + // inside test + return signDetermination2(k0, k1, k2, k3, face, node, dt); + } + else + { + // Case c: + if (sameSign(k0, k3)) + return false; + // inside test + return signDetermination1(k0, k1, k2, k3, face, node, dt); + } + return false; +} +static SIMD_FORCE_INLINE bool conservativeCulling(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& mrg) +{ + if (k0 > mrg && k1 > mrg && k2 > mrg && k3 > mrg) + return true; + if (k0 < -mrg && k1 < -mrg && k2 < -mrg && k3 < -mrg) + return true; + return false; +} + +static SIMD_FORCE_INLINE bool bernsteinVFTest(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& mrg, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt) +{ + if (conservativeCulling(k0, k1, k2, k3, mrg)) + return false; + return coplanarAndInsideTest(k0, k1, k2, k3, face, node, dt); +} + +static SIMD_FORCE_INLINE void deCasteljau(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& t0, btScalar& k10, btScalar& k20, btScalar& k30, btScalar& k21, btScalar& k12) +{ + k10 = k0*(1.0-t0) + k1*t0; + btScalar k11 = k1*(1.0-t0) + k2*t0; + k12 = k2*(1.0-t0) + k3*t0; + k20 = k10*(1.0-t0) + k11*t0; + k21 = k11*(1.0-t0) + k12*t0; + k30 = k20*(1.0-t0) + k21*t0; +} +static SIMD_FORCE_INLINE bool bernsteinVFTest(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg) +{ + btScalar k0, k1, k2, k3; + getBernsteinCoeff(face, node, dt, k0, k1, k2, k3); + if (conservativeCulling(k0, k1, k2, k3, mrg)) + return false; + return true; + if (diffSign(k2-2.0*k1+k0, k3-2.0*k2+k1)) + { + btScalar k10, k20, k30, k21, k12; + btScalar t0 = (k2-2.0*k1+k0)/(k0-3.0*k1+3.0*k2-k3); + deCasteljau(k0, k1, k2, k3, t0, k10, k20, k30, k21, k12); + return bernsteinVFTest(k0, k10, k20, k30, mrg, face, node, dt) || bernsteinVFTest(k30, k21, k12, k3, mrg, face, node, dt); + } + return coplanarAndInsideTest(k0, k1, k2, k3, face, node, dt); +} + +static SIMD_FORCE_INLINE bool continuousCollisionDetection(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg, btVector3& bary) +{ + if (hasSeparatingPlane(face, node, dt)) + return false; + btVector3 x21 = face->m_n[1]->m_x - face->m_n[0]->m_x; + btVector3 x31 = face->m_n[2]->m_x - face->m_n[0]->m_x; + btVector3 x41 = node->m_x - face->m_n[0]->m_x; + btVector3 v21 = face->m_n[1]->m_v - face->m_n[0]->m_v; + btVector3 v31 = face->m_n[2]->m_v - face->m_n[0]->m_v; + btVector3 v41 = node->m_v - face->m_n[0]->m_v; + btVector3 a = x21.cross(x31); + btVector3 b = x21.cross(v31) + v21.cross(x31); + btVector3 c = v21.cross(v31); + btVector3 d = x41; + btVector3 e = v41; + btScalar a0 = a.dot(d); + btScalar a1 = a.dot(e) + b.dot(d); + btScalar a2 = c.dot(d) + b.dot(e); + btScalar a3 = c.dot(e); + btScalar eps = SAFE_EPSILON; + int num_roots = 0; + btScalar roots[3]; + if (std::abs(a3) < eps) + { + // cubic term is zero + if (std::abs(a2) < eps) + { + if (std::abs(a1) < eps) + { + if (std::abs(a0) < eps) + { + num_roots = 2; + roots[0] = 0; + roots[1] = dt; + } + } + else + { + num_roots = 1; + roots[0] = -a0/a1; + } + } + else + { + num_roots = SolveP2(roots, a1/a2, a0/a2); + } + } + else + { + num_roots = SolveP3(roots, a2/a3, a1/a3, a0/a3); + } +// std::sort(roots, roots+num_roots); + if (num_roots > 1) + { + if (roots[0] > roots[1]) + btSwap(roots[0], roots[1]); + } + if (num_roots > 2) + { + if (roots[0] > roots[2]) + btSwap(roots[0], roots[2]); + if (roots[1] > roots[2]) + btSwap(roots[1], roots[2]); + } + for (int r = 0; r < num_roots; ++r) + { + double root = roots[r]; + if (root <= 0) + continue; + if (root > dt + SIMD_EPSILON) + return false; + btVector3 x1 = face->m_n[0]->m_x + root * face->m_n[0]->m_v; + btVector3 x2 = face->m_n[1]->m_x + root * face->m_n[1]->m_v; + btVector3 x3 = face->m_n[2]->m_x + root * face->m_n[2]->m_v; + btVector3 x4 = node->m_x + root * node->m_v; + btVector3 normal = (x2-x1).cross(x3-x1); + normal.safeNormalize(); + if (proximityTest(x1, x2, x3, x4, normal, mrg, bary)) + return true; + } + return false; +} +static SIMD_FORCE_INLINE bool bernsteinCCD(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg, btVector3& bary) +{ + if (!bernsteinVFTest(face, node, dt, mrg)) + return false; + if (!continuousCollisionDetection(face, node, dt, 1e-6, bary)) + return false; + return true; +} + // // btSymMatrix // @@ -373,6 +938,26 @@ static inline btMatrix3x3 OuterProduct(const btScalar* v1,const btScalar* v2,con return (m); } +static inline btMatrix3x3 OuterProduct(const btVector3& v1,const btVector3& v2) +{ + btMatrix3x3 m; + btScalar a11 = v1[0] * v2[0]; + btScalar a12 = v1[0] * v2[1]; + btScalar a13 = v1[0] * v2[2]; + + btScalar a21 = v1[1] * v2[0]; + btScalar a22 = v1[1] * v2[1]; + btScalar a23 = v1[1] * v2[2]; + + btScalar a31 = v1[2] * v2[0]; + btScalar a32 = v1[2] * v2[1]; + btScalar a33 = v1[2] * v2[2]; + m[0] = btVector3(a11, a12, a13); + m[1] = btVector3(a21, a22, a23); + m[2] = btVector3(a31, a32, a33); + return (m); +} + // static inline btMatrix3x3 Add(const btMatrix3x3& a, @@ -1070,8 +1655,8 @@ struct btSoftColliders if (!n.m_battach) { - // check for collision at x_{n+1}^* as well at x_n - if (psb->checkDeformableContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predict = */ true) || psb->checkDeformableContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predict = */ true)) + // check for collision at x_{n+1}^* + if (psb->checkDeformableContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predict = */ true)) { const btScalar ima = n.m_im; // todo: collision between multibody and fixed deformable node will be missed. @@ -1159,7 +1744,6 @@ struct btSoftColliders btSoftBody::Node* n0 = f.m_n[0]; btSoftBody::Node* n1 = f.m_n[1]; btSoftBody::Node* n2 = f.m_n[2]; - const btScalar m = (n0->m_im > 0 && n1->m_im > 0 && n2->m_im > 0 )? dynmargin : stamargin; btSoftBody::DeformableFaceRigidContact c; btVector3 contact_point; @@ -1174,18 +1758,19 @@ struct btSoftColliders if (ms > 0) { // resolve contact at x_n - psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, /*predict = */ false); +// psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, /*predict = */ false); btSoftBody::sCti& cti = c.m_cti; c.m_contactPoint = contact_point; c.m_bary = bary; // todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices c.m_weights = btScalar(2)/(btScalar(1) + bary.length2()) * bary; c.m_face = &f; + // friction is handled by the nodes to prevent sticking +// const btScalar fc = 0; const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); // the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf ima = bary.getX()*c.m_weights.getX() * n0->m_im + bary.getY()*c.m_weights.getY() * n1->m_im + bary.getZ()*c.m_weights.getZ() * n2->m_im; - c.m_c2 = ima; c.m_c3 = fc; c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; @@ -1316,19 +1901,11 @@ struct btSoftColliders { btSoftBody::Node* node = (btSoftBody::Node*)lnode->data; btSoftBody::Face* face = (btSoftBody::Face*)lface->data; - - btVector3 o = node->m_x; - btVector3 p; - btScalar d = SIMD_INFINITY; - ProjectOrigin(face->m_n[0]->m_x - o, - face->m_n[1]->m_x - o, - face->m_n[2]->m_x - o, - p, d); - const btScalar m = mrg + (o - node->m_q).safeNorm() * 2; - if (d < (m * m)) + btVector3 bary; + if (proximityTest(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, node->m_x, face->m_normal, mrg, bary)) { const btSoftBody::Node* n[] = {face->m_n[0], face->m_n[1], face->m_n[2]}; - const btVector3 w = BaryCoord(n[0]->m_x, n[1]->m_x, n[2]->m_x, p + o); + const btVector3 w = bary; const btScalar ma = node->m_im; btScalar mb = BaryEval(n[0]->m_im, n[1]->m_im, n[2]->m_im, w); if ((n[0]->m_im <= 0) || @@ -1341,20 +1918,14 @@ struct btSoftColliders if (ms > 0) { btSoftBody::DeformableFaceNodeContact c; - if (useFaceNormal) - c.m_normal = face->m_normal; - else - c.m_normal = p / -btSqrt(d); + c.m_normal = face->m_normal; + if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0) + c.m_normal = -face->m_normal; c.m_margin = mrg; c.m_node = node; c.m_face = face; c.m_bary = w; - // todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices - c.m_weights = btScalar(2)/(btScalar(1) + w.length2()) * w; c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF; - // the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf - c.m_imf = c.m_bary[0]*c.m_weights[0] * n[0]->m_im + c.m_bary[1]*c.m_weights[1] * n[1]->m_im + c.m_bary[2]*c.m_weights[2] * n[2]->m_im; - c.m_c0 = btScalar(1)/(ma + c.m_imf); psb[0]->m_faceNodeContacts.push_back(c); } } @@ -1372,69 +1943,152 @@ struct btSoftColliders void Process(const btDbvntNode* lface1, const btDbvntNode* lface2) { - btSoftBody::Face* f = (btSoftBody::Face*)lface1->data; - btSoftBody::Face* face = (btSoftBody::Face*)lface2->data; + btSoftBody::Face* f1 = (btSoftBody::Face*)lface1->data; + btSoftBody::Face* f2 = (btSoftBody::Face*)lface2->data; + if (f1 != f2) + { + Repel(f1, f2); + Repel(f2, f1); + } + } + void Repel(btSoftBody::Face* f1, btSoftBody::Face* f2) + { + //#define REPEL_NEIGHBOR 1 +#ifndef REPEL_NEIGHBOR for (int node_id = 0; node_id < 3; ++node_id) { - btSoftBody::Node* node = f->m_n[node_id]; - bool skip = false; + btSoftBody::Node* node = f1->m_n[node_id]; for (int i = 0; i < 3; ++i) { - if (face->m_n[i] == node) + if (f2->m_n[i] == node) + return; + } + } +#endif + bool skip = false; + for (int node_id = 0; node_id < 3; ++node_id) + { + btSoftBody::Node* node = f1->m_n[node_id]; +#ifdef REPEL_NEIGHBOR + for (int i = 0; i < 3; ++i) + { + if (f2->m_n[i] == node) { skip = true; break; } } if (skip) + { + skip = false; + continue; + } +#endif + btSoftBody::Face* face = f2; + btVector3 bary; + if (!proximityTest(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, node->m_x, face->m_normal, mrg, bary)) continue; - btVector3 o = node->m_x; - btVector3 p; - btScalar d = SIMD_INFINITY; - ProjectOrigin(face->m_n[0]->m_x - o, - face->m_n[1]->m_x - o, - face->m_n[2]->m_x - o, - p, d); - const btScalar m = mrg + (o - node->m_q).safeNorm() * 2; - if (d < (m * m)) + btSoftBody::DeformableFaceNodeContact c; + c.m_normal = face->m_normal; + if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0) + c.m_normal = -face->m_normal; + c.m_margin = mrg; + c.m_node = node; + c.m_face = face; + c.m_bary = bary; + c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF; + psb[0]->m_faceNodeContacts.push_back(c); + } + } + btSoftBody* psb[2]; + btScalar mrg; + bool useFaceNormal; + }; + + struct CollideCCD : btDbvt::ICollide + { + void Process(const btDbvtNode* lnode, + const btDbvtNode* lface) + { + btSoftBody::Node* node = (btSoftBody::Node*)lnode->data; + btSoftBody::Face* face = (btSoftBody::Face*)lface->data; + btVector3 bary; + if (bernsteinCCD(face, node, dt, SAFE_EPSILON, bary)) + { + btSoftBody::DeformableFaceNodeContact c; + c.m_normal = face->m_normal; + if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0) + c.m_normal = -face->m_normal; + c.m_node = node; + c.m_face = face; + c.m_bary = bary; + c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF; + psb[0]->m_faceNodeContacts.push_back(c); + } + } + void Process(const btDbvntNode* lface1, + const btDbvntNode* lface2) + { + btSoftBody::Face* f1 = (btSoftBody::Face*)lface1->data; + btSoftBody::Face* f2 = (btSoftBody::Face*)lface2->data; + if (f1 != f2) + { + Repel(f1, f2); + Repel(f2, f1); + } + } + void Repel(btSoftBody::Face* f1, btSoftBody::Face* f2) + { + //#define REPEL_NEIGHBOR 1 +#ifndef REPEL_NEIGHBOR + for (int node_id = 0; node_id < 3; ++node_id) + { + btSoftBody::Node* node = f1->m_n[node_id]; + for (int i = 0; i < 3; ++i) { - const btSoftBody::Node* n[] = {face->m_n[0], face->m_n[1], face->m_n[2]}; - const btVector3 w = BaryCoord(n[0]->m_x, n[1]->m_x, n[2]->m_x, p + o); - const btScalar ma = node->m_im; - btScalar mb = BaryEval(n[0]->m_im, n[1]->m_im, n[2]->m_im, w); - if ((n[0]->m_im <= 0) || - (n[1]->m_im <= 0) || - (n[2]->m_im <= 0)) - { - mb = 0; - } - const btScalar ms = ma + mb; - if (ms > 0) + if (f2->m_n[i] == node) + return; + } + } +#endif + bool skip = false; + for (int node_id = 0; node_id < 3; ++node_id) + { + btSoftBody::Node* node = f1->m_n[node_id]; +#ifdef REPEL_NEIGHBOR + for (int i = 0; i < 3; ++i) + { + if (f2->m_n[i] == node) { - btSoftBody::DeformableFaceNodeContact c; - if (useFaceNormal) - c.m_normal = face->m_normal; - else - c.m_normal = p / -btSqrt(d); - c.m_margin = mrg; - c.m_node = node; - c.m_face = face; - c.m_bary = w; - // todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices - c.m_weights = btScalar(2)/(btScalar(1) + w.length2()) * w; - c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF; - // the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf - c.m_imf = c.m_bary[0]*c.m_weights[0] * n[0]->m_im + c.m_bary[1]*c.m_weights[1] * n[1]->m_im + c.m_bary[2]*c.m_weights[2] * n[2]->m_im; - c.m_c0 = btScalar(1)/(ma + c.m_imf); - psb[0]->m_faceNodeContacts.push_back(c); + skip = true; + break; } } + if (skip) + { + skip = false; + continue; + } +#endif + btSoftBody::Face* face = f2; + btVector3 bary; + if (bernsteinCCD(face, node, dt, SAFE_EPSILON, bary)) + { + btSoftBody::DeformableFaceNodeContact c; + c.m_normal = face->m_normal; + if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0) + c.m_normal = -face->m_normal; + c.m_node = node; + c.m_face = face; + c.m_bary = bary; + c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF; + psb[0]->m_faceNodeContacts.push_back(c); + } } } btSoftBody* psb[2]; - btScalar mrg; + btScalar dt, mrg; bool useFaceNormal; }; }; - #endif //_BT_SOFT_BODY_INTERNALS_H diff --git a/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp index 56d8083f22..5b65216e4b 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp +++ b/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp @@ -48,9 +48,10 @@ btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() } #include <stdio.h> - +#include "LinearMath/btQuickprof.h" void btSoftRigidCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { + BT_PROFILE("btSoftRigidCollisionAlgorithm::processCollision"); (void)dispatchInfo; (void)resultOut; //printf("btSoftRigidCollisionAlgorithm\n"); diff --git a/thirdparty/bullet/BulletSoftBody/poly34.cpp b/thirdparty/bullet/BulletSoftBody/poly34.cpp new file mode 100644 index 0000000000..819d0c79f7 --- /dev/null +++ b/thirdparty/bullet/BulletSoftBody/poly34.cpp @@ -0,0 +1,419 @@ +// poly34.cpp : solution of cubic and quartic equation +// (c) Khashin S.I. http://math.ivanovo.ac.ru/dalgebra/Khashin/index.html +// khash2 (at) gmail.com +// Thanks to Alexandr Rakhmanin <rakhmanin (at) gmail.com> +// public domain +// +#include <math.h> + +#include "poly34.h" // solution of cubic and quartic equation +#define TwoPi 6.28318530717958648 +const btScalar eps = SIMD_EPSILON; + +//============================================================================= +// _root3, root3 from http://prografix.narod.ru +//============================================================================= +static SIMD_FORCE_INLINE btScalar _root3(btScalar x) +{ + btScalar s = 1.; + while (x < 1.) { + x *= 8.; + s *= 0.5; + } + while (x > 8.) { + x *= 0.125; + s *= 2.; + } + btScalar r = 1.5; + r -= 1. / 3. * (r - x / (r * r)); + r -= 1. / 3. * (r - x / (r * r)); + r -= 1. / 3. * (r - x / (r * r)); + r -= 1. / 3. * (r - x / (r * r)); + r -= 1. / 3. * (r - x / (r * r)); + r -= 1. / 3. * (r - x / (r * r)); + return r * s; +} + +btScalar SIMD_FORCE_INLINE root3(btScalar x) +{ + if (x > 0) + return _root3(x); + else if (x < 0) + return -_root3(-x); + else + return 0.; +} + +// x - array of size 2 +// return 2: 2 real roots x[0], x[1] +// return 0: pair of complex roots: x[0]i*x[1] +int SolveP2(btScalar* x, btScalar a, btScalar b) +{ // solve equation x^2 + a*x + b = 0 + btScalar D = 0.25 * a * a - b; + if (D >= 0) { + D = sqrt(D); + x[0] = -0.5 * a + D; + x[1] = -0.5 * a - D; + return 2; + } + x[0] = -0.5 * a; + x[1] = sqrt(-D); + return 0; +} +//--------------------------------------------------------------------------- +// x - array of size 3 +// In case 3 real roots: => x[0], x[1], x[2], return 3 +// 2 real roots: x[0], x[1], return 2 +// 1 real root : x[0], x[1] i*x[2], return 1 +int SolveP3(btScalar* x, btScalar a, btScalar b, btScalar c) +{ // solve cubic equation x^3 + a*x^2 + b*x + c = 0 + btScalar a2 = a * a; + btScalar q = (a2 - 3 * b) / 9; + if (q < 0) + q = eps; + btScalar r = (a * (2 * a2 - 9 * b) + 27 * c) / 54; + // equation x^3 + q*x + r = 0 + btScalar r2 = r * r; + btScalar q3 = q * q * q; + btScalar A, B; + if (r2 <= (q3 + eps)) { //<<-- FIXED! + btScalar t = r / sqrt(q3); + if (t < -1) + t = -1; + if (t > 1) + t = 1; + t = acos(t); + a /= 3; + q = -2 * sqrt(q); + x[0] = q * cos(t / 3) - a; + x[1] = q * cos((t + TwoPi) / 3) - a; + x[2] = q * cos((t - TwoPi) / 3) - a; + return (3); + } + else { + //A =-pow(fabs(r)+sqrt(r2-q3),1./3); + A = -root3(fabs(r) + sqrt(r2 - q3)); + if (r < 0) + A = -A; + B = (A == 0 ? 0 : q / A); + + a /= 3; + x[0] = (A + B) - a; + x[1] = -0.5 * (A + B) - a; + x[2] = 0.5 * sqrt(3.) * (A - B); + if (fabs(x[2]) < eps) { + x[2] = x[1]; + return (2); + } + return (1); + } +} // SolveP3(btScalar *x,btScalar a,btScalar b,btScalar c) { +//--------------------------------------------------------------------------- +// a>=0! +void CSqrt(btScalar x, btScalar y, btScalar& a, btScalar& b) // returns: a+i*s = sqrt(x+i*y) +{ + btScalar r = sqrt(x * x + y * y); + if (y == 0) { + r = sqrt(r); + if (x >= 0) { + a = r; + b = 0; + } + else { + a = 0; + b = r; + } + } + else { // y != 0 + a = sqrt(0.5 * (x + r)); + b = 0.5 * y / a; + } +} +//--------------------------------------------------------------------------- +int SolveP4Bi(btScalar* x, btScalar b, btScalar d) // solve equation x^4 + b*x^2 + d = 0 +{ + btScalar D = b * b - 4 * d; + if (D >= 0) { + btScalar sD = sqrt(D); + btScalar x1 = (-b + sD) / 2; + btScalar x2 = (-b - sD) / 2; // x2 <= x1 + if (x2 >= 0) // 0 <= x2 <= x1, 4 real roots + { + btScalar sx1 = sqrt(x1); + btScalar sx2 = sqrt(x2); + x[0] = -sx1; + x[1] = sx1; + x[2] = -sx2; + x[3] = sx2; + return 4; + } + if (x1 < 0) // x2 <= x1 < 0, two pair of imaginary roots + { + btScalar sx1 = sqrt(-x1); + btScalar sx2 = sqrt(-x2); + x[0] = 0; + x[1] = sx1; + x[2] = 0; + x[3] = sx2; + return 0; + } + // now x2 < 0 <= x1 , two real roots and one pair of imginary root + btScalar sx1 = sqrt(x1); + btScalar sx2 = sqrt(-x2); + x[0] = -sx1; + x[1] = sx1; + x[2] = 0; + x[3] = sx2; + return 2; + } + else { // if( D < 0 ), two pair of compex roots + btScalar sD2 = 0.5 * sqrt(-D); + CSqrt(-0.5 * b, sD2, x[0], x[1]); + CSqrt(-0.5 * b, -sD2, x[2], x[3]); + return 0; + } // if( D>=0 ) +} // SolveP4Bi(btScalar *x, btScalar b, btScalar d) // solve equation x^4 + b*x^2 d +//--------------------------------------------------------------------------- +#define SWAP(a, b) \ +{ \ +t = b; \ +b = a; \ +a = t; \ +} +static void dblSort3(btScalar& a, btScalar& b, btScalar& c) // make: a <= b <= c +{ + btScalar t; + if (a > b) + SWAP(a, b); // now a<=b + if (c < b) { + SWAP(b, c); // now a<=b, b<=c + if (a > b) + SWAP(a, b); // now a<=b + } +} +//--------------------------------------------------------------------------- +int SolveP4De(btScalar* x, btScalar b, btScalar c, btScalar d) // solve equation x^4 + b*x^2 + c*x + d +{ + //if( c==0 ) return SolveP4Bi(x,b,d); // After that, c!=0 + if (fabs(c) < 1e-14 * (fabs(b) + fabs(d))) + return SolveP4Bi(x, b, d); // After that, c!=0 + + int res3 = SolveP3(x, 2 * b, b * b - 4 * d, -c * c); // solve resolvent + // by Viet theorem: x1*x2*x3=-c*c not equals to 0, so x1!=0, x2!=0, x3!=0 + if (res3 > 1) // 3 real roots, + { + dblSort3(x[0], x[1], x[2]); // sort roots to x[0] <= x[1] <= x[2] + // Note: x[0]*x[1]*x[2]= c*c > 0 + if (x[0] > 0) // all roots are positive + { + btScalar sz1 = sqrt(x[0]); + btScalar sz2 = sqrt(x[1]); + btScalar sz3 = sqrt(x[2]); + // Note: sz1*sz2*sz3= -c (and not equal to 0) + if (c > 0) { + x[0] = (-sz1 - sz2 - sz3) / 2; + x[1] = (-sz1 + sz2 + sz3) / 2; + x[2] = (+sz1 - sz2 + sz3) / 2; + x[3] = (+sz1 + sz2 - sz3) / 2; + return 4; + } + // now: c<0 + x[0] = (-sz1 - sz2 + sz3) / 2; + x[1] = (-sz1 + sz2 - sz3) / 2; + x[2] = (+sz1 - sz2 - sz3) / 2; + x[3] = (+sz1 + sz2 + sz3) / 2; + return 4; + } // if( x[0] > 0) // all roots are positive + // now x[0] <= x[1] < 0, x[2] > 0 + // two pair of comlex roots + btScalar sz1 = sqrt(-x[0]); + btScalar sz2 = sqrt(-x[1]); + btScalar sz3 = sqrt(x[2]); + + if (c > 0) // sign = -1 + { + x[0] = -sz3 / 2; + x[1] = (sz1 - sz2) / 2; // x[0]i*x[1] + x[2] = sz3 / 2; + x[3] = (-sz1 - sz2) / 2; // x[2]i*x[3] + return 0; + } + // now: c<0 , sign = +1 + x[0] = sz3 / 2; + x[1] = (-sz1 + sz2) / 2; + x[2] = -sz3 / 2; + x[3] = (sz1 + sz2) / 2; + return 0; + } // if( res3>1 ) // 3 real roots, + // now resoventa have 1 real and pair of compex roots + // x[0] - real root, and x[0]>0, + // x[1]i*x[2] - complex roots, + // x[0] must be >=0. But one times x[0]=~ 1e-17, so: + if (x[0] < 0) + x[0] = 0; + btScalar sz1 = sqrt(x[0]); + btScalar szr, szi; + CSqrt(x[1], x[2], szr, szi); // (szr+i*szi)^2 = x[1]+i*x[2] + if (c > 0) // sign = -1 + { + x[0] = -sz1 / 2 - szr; // 1st real root + x[1] = -sz1 / 2 + szr; // 2nd real root + x[2] = sz1 / 2; + x[3] = szi; + return 2; + } + // now: c<0 , sign = +1 + x[0] = sz1 / 2 - szr; // 1st real root + x[1] = sz1 / 2 + szr; // 2nd real root + x[2] = -sz1 / 2; + x[3] = szi; + return 2; +} // SolveP4De(btScalar *x, btScalar b, btScalar c, btScalar d) // solve equation x^4 + b*x^2 + c*x + d +//----------------------------------------------------------------------------- +btScalar N4Step(btScalar x, btScalar a, btScalar b, btScalar c, btScalar d) // one Newton step for x^4 + a*x^3 + b*x^2 + c*x + d +{ + btScalar fxs = ((4 * x + 3 * a) * x + 2 * b) * x + c; // f'(x) + if (fxs == 0) + return x; //return 1e99; <<-- FIXED! + btScalar fx = (((x + a) * x + b) * x + c) * x + d; // f(x) + return x - fx / fxs; +} +//----------------------------------------------------------------------------- +// x - array of size 4 +// return 4: 4 real roots x[0], x[1], x[2], x[3], possible multiple roots +// return 2: 2 real roots x[0], x[1] and complex x[2]i*x[3], +// return 0: two pair of complex roots: x[0]i*x[1], x[2]i*x[3], +int SolveP4(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d) +{ // solve equation x^4 + a*x^3 + b*x^2 + c*x + d by Dekart-Euler method + // move to a=0: + btScalar d1 = d + 0.25 * a * (0.25 * b * a - 3. / 64 * a * a * a - c); + btScalar c1 = c + 0.5 * a * (0.25 * a * a - b); + btScalar b1 = b - 0.375 * a * a; + int res = SolveP4De(x, b1, c1, d1); + if (res == 4) { + x[0] -= a / 4; + x[1] -= a / 4; + x[2] -= a / 4; + x[3] -= a / 4; + } + else if (res == 2) { + x[0] -= a / 4; + x[1] -= a / 4; + x[2] -= a / 4; + } + else { + x[0] -= a / 4; + x[2] -= a / 4; + } + // one Newton step for each real root: + if (res > 0) { + x[0] = N4Step(x[0], a, b, c, d); + x[1] = N4Step(x[1], a, b, c, d); + } + if (res > 2) { + x[2] = N4Step(x[2], a, b, c, d); + x[3] = N4Step(x[3], a, b, c, d); + } + return res; +} +//----------------------------------------------------------------------------- +#define F5(t) (((((t + a) * t + b) * t + c) * t + d) * t + e) +//----------------------------------------------------------------------------- +btScalar SolveP5_1(btScalar a, btScalar b, btScalar c, btScalar d, btScalar e) // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 +{ + int cnt; + if (fabs(e) < eps) + return 0; + + btScalar brd = fabs(a); // brd - border of real roots + if (fabs(b) > brd) + brd = fabs(b); + if (fabs(c) > brd) + brd = fabs(c); + if (fabs(d) > brd) + brd = fabs(d); + if (fabs(e) > brd) + brd = fabs(e); + brd++; // brd - border of real roots + + btScalar x0, f0; // less than root + btScalar x1, f1; // greater than root + btScalar x2, f2, f2s; // next values, f(x2), f'(x2) + btScalar dx = 0; + + if (e < 0) { + x0 = 0; + x1 = brd; + f0 = e; + f1 = F5(x1); + x2 = 0.01 * brd; + } // positive root + else { + x0 = -brd; + x1 = 0; + f0 = F5(x0); + f1 = e; + x2 = -0.01 * brd; + } // negative root + + if (fabs(f0) < eps) + return x0; + if (fabs(f1) < eps) + return x1; + + // now x0<x1, f(x0)<0, f(x1)>0 + // Firstly 10 bisections + for (cnt = 0; cnt < 10; cnt++) { + x2 = (x0 + x1) / 2; // next point + //x2 = x0 - f0*(x1 - x0) / (f1 - f0); // next point + f2 = F5(x2); // f(x2) + if (fabs(f2) < eps) + return x2; + if (f2 > 0) { + x1 = x2; + f1 = f2; + } + else { + x0 = x2; + f0 = f2; + } + } + + // At each step: + // x0<x1, f(x0)<0, f(x1)>0. + // x2 - next value + // we hope that x0 < x2 < x1, but not necessarily + do { + if (cnt++ > 50) + break; + if (x2 <= x0 || x2 >= x1) + x2 = (x0 + x1) / 2; // now x0 < x2 < x1 + f2 = F5(x2); // f(x2) + if (fabs(f2) < eps) + return x2; + if (f2 > 0) { + x1 = x2; + f1 = f2; + } + else { + x0 = x2; + f0 = f2; + } + f2s = (((5 * x2 + 4 * a) * x2 + 3 * b) * x2 + 2 * c) * x2 + d; // f'(x2) + if (fabs(f2s) < eps) { + x2 = 1e99; + continue; + } + dx = f2 / f2s; + x2 -= dx; + } while (fabs(dx) > eps); + return x2; +} // SolveP5_1(btScalar a,btScalar b,btScalar c,btScalar d,btScalar e) // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 +//----------------------------------------------------------------------------- +int SolveP5(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d, btScalar e) // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 +{ + btScalar r = x[0] = SolveP5_1(a, b, c, d, e); + btScalar a1 = a + r, b1 = b + r * a1, c1 = c + r * b1, d1 = d + r * c1; + return 1 + SolveP4(x + 1, a1, b1, c1, d1); +} // SolveP5(btScalar *x,btScalar a,btScalar b,btScalar c,btScalar d,btScalar e) // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 +//----------------------------------------------------------------------------- diff --git a/thirdparty/bullet/BulletSoftBody/poly34.h b/thirdparty/bullet/BulletSoftBody/poly34.h new file mode 100644 index 0000000000..32ad5d7da5 --- /dev/null +++ b/thirdparty/bullet/BulletSoftBody/poly34.h @@ -0,0 +1,38 @@ +// poly34.h : solution of cubic and quartic equation +// (c) Khashin S.I. http://math.ivanovo.ac.ru/dalgebra/Khashin/index.html +// khash2 (at) gmail.com + +#ifndef POLY_34 +#define POLY_34 +#include "LinearMath/btScalar.h" +// x - array of size 2 +// return 2: 2 real roots x[0], x[1] +// return 0: pair of complex roots: x[0]i*x[1] +int SolveP2(btScalar* x, btScalar a, btScalar b); // solve equation x^2 + a*x + b = 0 + +// x - array of size 3 +// return 3: 3 real roots x[0], x[1], x[2] +// return 1: 1 real root x[0] and pair of complex roots: x[1]i*x[2] +int SolveP3(btScalar* x, btScalar a, btScalar b, btScalar c); // solve cubic equation x^3 + a*x^2 + b*x + c = 0 + +// x - array of size 4 +// return 4: 4 real roots x[0], x[1], x[2], x[3], possible multiple roots +// return 2: 2 real roots x[0], x[1] and complex x[2]i*x[3], +// return 0: two pair of complex roots: x[0]i*x[1], x[2]i*x[3], +int SolveP4(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d); // solve equation x^4 + a*x^3 + b*x^2 + c*x + d = 0 by Dekart-Euler method + +// x - array of size 5 +// return 5: 5 real roots x[0], x[1], x[2], x[3], x[4], possible multiple roots +// return 3: 3 real roots x[0], x[1], x[2] and complex x[3]i*x[4], +// return 1: 1 real root x[0] and two pair of complex roots: x[1]i*x[2], x[3]i*x[4], +int SolveP5(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d, btScalar e); // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 + +//----------------------------------------------------------------------------- +// And some additional functions for internal use. +// Your may remove this definitions from here +int SolveP4Bi(btScalar* x, btScalar b, btScalar d); // solve equation x^4 + b*x^2 + d = 0 +int SolveP4De(btScalar* x, btScalar b, btScalar c, btScalar d); // solve equation x^4 + b*x^2 + c*x + d = 0 +void CSqrt(btScalar x, btScalar y, btScalar& a, btScalar& b); // returns as a+i*s, sqrt(x+i*y) +btScalar N4Step(btScalar x, btScalar a, btScalar b, btScalar c, btScalar d); // one Newton step for x^4 + a*x^3 + b*x^2 + c*x + d +btScalar SolveP5_1(btScalar a, btScalar b, btScalar c, btScalar d, btScalar e); // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0 +#endif diff --git a/thirdparty/bullet/LinearMath/btImplicitQRSVD.h b/thirdparty/bullet/LinearMath/btImplicitQRSVD.h index 7b4cfaf21e..aaedc964f6 100644 --- a/thirdparty/bullet/LinearMath/btImplicitQRSVD.h +++ b/thirdparty/bullet/LinearMath/btImplicitQRSVD.h @@ -41,7 +41,7 @@ #ifndef btImplicitQRSVD_h #define btImplicitQRSVD_h - +#include <limits> #include "btMatrix3x3.h" class btMatrix2x2 { @@ -753,7 +753,7 @@ inline int singularValueDecomposition(const btMatrix3x3& A, btMatrix3x3& V, btScalar tol = 128*std::numeric_limits<btScalar>::epsilon()) { - using std::fabs; +// using std::fabs; btMatrix3x3 B = A; U.setIdentity(); V.setIdentity(); diff --git a/thirdparty/bullet/LinearMath/btMatrix3x3.h b/thirdparty/bullet/LinearMath/btMatrix3x3.h index cc33a68664..9c90fee1d2 100644 --- a/thirdparty/bullet/LinearMath/btMatrix3x3.h +++ b/thirdparty/bullet/LinearMath/btMatrix3x3.h @@ -26,10 +26,12 @@ subject to the following restrictions: #endif #if defined(BT_USE_SSE) +#define v0000 (_mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f)) #define v1000 (_mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f)) #define v0100 (_mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f)) #define v0010 (_mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f)) #elif defined(BT_USE_NEON) +const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0000) = {0.0f, 0.0f, 0.0f, 0.0f}; const btSimdFloat4 ATTRIBUTE_ALIGNED16(v1000) = {1.0f, 0.0f, 0.0f, 0.0f}; const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0100) = {0.0f, 1.0f, 0.0f, 0.0f}; const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0010) = {0.0f, 0.0f, 1.0f, 0.0f}; @@ -330,6 +332,20 @@ public: btScalar(0.0), btScalar(0.0), btScalar(1.0)); #endif } + + /**@brief Set the matrix to the identity */ + void setZero() + { +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + m_el[0] = v0000; + m_el[1] = v0000; + m_el[2] = v0000; +#else + setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(0.0)); +#endif + } static const btMatrix3x3& getIdentity() { diff --git a/thirdparty/bullet/LinearMath/btMatrixX.h b/thirdparty/bullet/LinearMath/btMatrixX.h index 961c94dc63..bb0f0dd259 100644 --- a/thirdparty/bullet/LinearMath/btMatrixX.h +++ b/thirdparty/bullet/LinearMath/btMatrixX.h @@ -346,10 +346,9 @@ struct btMatrixX T dotProd = 0; { { - int r = rows(); int c = cols(); - for (int k = 0; k < cols(); k++) + for (int k = 0; k < c; k++) { T w = (*this)(i, k); if (other(k, j) != 0.f) diff --git a/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h b/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h new file mode 100644 index 0000000000..33bab8d650 --- /dev/null +++ b/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h @@ -0,0 +1,83 @@ +// +// btModifiedGramSchmidt.h +// LinearMath +// +// Created by Xuchen Han on 4/4/20. +// + +#ifndef btModifiedGramSchmidt_h +#define btModifiedGramSchmidt_h + +#include "btReducedVector.h" +#include "btAlignedObjectArray.h" +#include <iostream> +#include <cmath> +template<class TV> +class btModifiedGramSchmidt +{ +public: + btAlignedObjectArray<TV> m_in; + btAlignedObjectArray<TV> m_out; + + btModifiedGramSchmidt(const btAlignedObjectArray<TV>& vecs): m_in(vecs) + { + m_out.resize(0); + } + + void solve() + { + m_out.resize(m_in.size()); + for (int i = 0; i < m_in.size(); ++i) + { +// printf("========= starting %d ==========\n", i); + TV v(m_in[i]); +// v.print(); + for (int j = 0; j < i; ++j) + { + v = v - v.proj(m_out[j]); +// v.print(); + } + v.normalize(); + m_out[i] = v; +// v.print(); + } + } + + void test() + { + std::cout << SIMD_EPSILON << std::endl; + printf("=======inputs=========\n"); + for (int i = 0; i < m_out.size(); ++i) + { + m_in[i].print(); + } + printf("=======output=========\n"); + for (int i = 0; i < m_out.size(); ++i) + { + m_out[i].print(); + } + btScalar eps = SIMD_EPSILON; + for (int i = 0; i < m_out.size(); ++i) + { + for (int j = 0; j < m_out.size(); ++j) + { + if (i == j) + { + if (std::abs(1.0-m_out[i].dot(m_out[j])) > eps)// && std::abs(m_out[i].dot(m_out[j])) > eps) + { + printf("vec[%d] is not unit, norm squared = %f\n", i,m_out[i].dot(m_out[j])); + } + } + else + { + if (std::abs(m_out[i].dot(m_out[j])) > eps) + { + printf("vec[%d] and vec[%d] is not orthogonal, dot product = %f\n", i, j, m_out[i].dot(m_out[j])); + } + } + } + } + } +}; +template class btModifiedGramSchmidt<btReducedVector>; +#endif /* btModifiedGramSchmidt_h */ diff --git a/thirdparty/bullet/LinearMath/btReducedVector.cpp b/thirdparty/bullet/LinearMath/btReducedVector.cpp new file mode 100644 index 0000000000..1539584e7e --- /dev/null +++ b/thirdparty/bullet/LinearMath/btReducedVector.cpp @@ -0,0 +1,170 @@ +// +// btReducedVector.cpp +// LinearMath +// +// Created by Xuchen Han on 4/4/20. +// +#include <stdio.h> +#include "btReducedVector.h" +#include <cmath> + +// returns the projection of this onto other +btReducedVector btReducedVector::proj(const btReducedVector& other) const +{ + btReducedVector ret(m_sz); + btScalar other_length2 = other.length2(); + if (other_length2 < SIMD_EPSILON) + { + return ret; + } + return other*(this->dot(other))/other_length2; +} + +void btReducedVector::normalize() +{ + if (this->length2() < SIMD_EPSILON) + { + m_indices.clear(); + m_vecs.clear(); + return; + } + *this /= std::sqrt(this->length2()); +} + +bool btReducedVector::testAdd() const +{ + int sz = 5; + btAlignedObjectArray<int> id1; + id1.push_back(1); + id1.push_back(3); + btAlignedObjectArray<btVector3> v1; + v1.push_back(btVector3(1,0,1)); + v1.push_back(btVector3(3,1,5)); + btAlignedObjectArray<int> id2; + id2.push_back(2); + id2.push_back(3); + id2.push_back(5); + btAlignedObjectArray<btVector3> v2; + v2.push_back(btVector3(2,3,1)); + v2.push_back(btVector3(3,4,9)); + v2.push_back(btVector3(0,4,0)); + btAlignedObjectArray<int> id3; + id3.push_back(1); + id3.push_back(2); + id3.push_back(3); + id3.push_back(5); + btAlignedObjectArray<btVector3> v3; + v3.push_back(btVector3(1,0,1)); + v3.push_back(btVector3(2,3,1)); + v3.push_back(btVector3(6,5,14)); + v3.push_back(btVector3(0,4,0)); + btReducedVector rv1(sz, id1, v1); + btReducedVector rv2(sz, id2, v2); + btReducedVector ans(sz, id3, v3); + bool ret = ((ans == rv1+rv2) && (ans == rv2+rv1)); + if (!ret) + printf("btReducedVector testAdd failed\n"); + return ret; +} + +bool btReducedVector::testMinus() const +{ + int sz = 5; + btAlignedObjectArray<int> id1; + id1.push_back(1); + id1.push_back(3); + btAlignedObjectArray<btVector3> v1; + v1.push_back(btVector3(1,0,1)); + v1.push_back(btVector3(3,1,5)); + btAlignedObjectArray<int> id2; + id2.push_back(2); + id2.push_back(3); + id2.push_back(5); + btAlignedObjectArray<btVector3> v2; + v2.push_back(btVector3(2,3,1)); + v2.push_back(btVector3(3,4,9)); + v2.push_back(btVector3(0,4,0)); + btAlignedObjectArray<int> id3; + id3.push_back(1); + id3.push_back(2); + id3.push_back(3); + id3.push_back(5); + btAlignedObjectArray<btVector3> v3; + v3.push_back(btVector3(-1,-0,-1)); + v3.push_back(btVector3(2,3,1)); + v3.push_back(btVector3(0,3,4)); + v3.push_back(btVector3(0,4,0)); + btReducedVector rv1(sz, id1, v1); + btReducedVector rv2(sz, id2, v2); + btReducedVector ans(sz, id3, v3); + bool ret = (ans == rv2-rv1); + if (!ret) + printf("btReducedVector testMinus failed\n"); + return ret; +} + +bool btReducedVector::testDot() const +{ + int sz = 5; + btAlignedObjectArray<int> id1; + id1.push_back(1); + id1.push_back(3); + btAlignedObjectArray<btVector3> v1; + v1.push_back(btVector3(1,0,1)); + v1.push_back(btVector3(3,1,5)); + btAlignedObjectArray<int> id2; + id2.push_back(2); + id2.push_back(3); + id2.push_back(5); + btAlignedObjectArray<btVector3> v2; + v2.push_back(btVector3(2,3,1)); + v2.push_back(btVector3(3,4,9)); + v2.push_back(btVector3(0,4,0)); + btReducedVector rv1(sz, id1, v1); + btReducedVector rv2(sz, id2, v2); + btScalar ans = 58; + bool ret = (ans == rv2.dot(rv1) && ans == rv1.dot(rv2)); + ans = 14+16+9+16+81; + ret &= (ans==rv2.dot(rv2)); + + if (!ret) + printf("btReducedVector testDot failed\n"); + return ret; +} + +bool btReducedVector::testMultiply() const +{ + int sz = 5; + btAlignedObjectArray<int> id1; + id1.push_back(1); + id1.push_back(3); + btAlignedObjectArray<btVector3> v1; + v1.push_back(btVector3(1,0,1)); + v1.push_back(btVector3(3,1,5)); + btScalar s = 2; + btReducedVector rv1(sz, id1, v1); + btAlignedObjectArray<int> id2; + id2.push_back(1); + id2.push_back(3); + btAlignedObjectArray<btVector3> v2; + v2.push_back(btVector3(2,0,2)); + v2.push_back(btVector3(6,2,10)); + btReducedVector ans(sz, id2, v2); + bool ret = (ans == rv1*s); + if (!ret) + printf("btReducedVector testMultiply failed\n"); + return ret; +} + +void btReducedVector::test() const +{ + bool ans = testAdd() && testMinus() && testDot() && testMultiply(); + if (ans) + { + printf("All tests passed\n"); + } + else + { + printf("Tests failed\n"); + } +} diff --git a/thirdparty/bullet/LinearMath/btReducedVector.h b/thirdparty/bullet/LinearMath/btReducedVector.h new file mode 100644 index 0000000000..83b5e581e5 --- /dev/null +++ b/thirdparty/bullet/LinearMath/btReducedVector.h @@ -0,0 +1,320 @@ +// +// btReducedVectors.h +// BulletLinearMath +// +// Created by Xuchen Han on 4/4/20. +// +#ifndef btReducedVectors_h +#define btReducedVectors_h +#include "btVector3.h" +#include "btMatrix3x3.h" +#include "btAlignedObjectArray.h" +#include <stdio.h> +#include <vector> +#include <algorithm> +struct TwoInts +{ + int a,b; +}; +inline bool operator<(const TwoInts& A, const TwoInts& B) +{ + return A.b < B.b; +} + + +// A helper vector type used for CG projections +class btReducedVector +{ +public: + btAlignedObjectArray<int> m_indices; + btAlignedObjectArray<btVector3> m_vecs; + int m_sz; // all m_indices value < m_sz +public: + btReducedVector():m_sz(0) + { + m_indices.resize(0); + m_vecs.resize(0); + m_indices.clear(); + m_vecs.clear(); + } + + btReducedVector(int sz): m_sz(sz) + { + m_indices.resize(0); + m_vecs.resize(0); + m_indices.clear(); + m_vecs.clear(); + } + + btReducedVector(int sz, const btAlignedObjectArray<int>& indices, const btAlignedObjectArray<btVector3>& vecs): m_sz(sz), m_indices(indices), m_vecs(vecs) + { + } + + void simplify() + { + btAlignedObjectArray<int> old_indices(m_indices); + btAlignedObjectArray<btVector3> old_vecs(m_vecs); + m_indices.resize(0); + m_vecs.resize(0); + m_indices.clear(); + m_vecs.clear(); + for (int i = 0; i < old_indices.size(); ++i) + { + if (old_vecs[i].length2() > SIMD_EPSILON) + { + m_indices.push_back(old_indices[i]); + m_vecs.push_back(old_vecs[i]); + } + } + } + + btReducedVector operator+(const btReducedVector& other) + { + btReducedVector ret(m_sz); + int i=0, j=0; + while (i < m_indices.size() && j < other.m_indices.size()) + { + if (m_indices[i] < other.m_indices[j]) + { + ret.m_indices.push_back(m_indices[i]); + ret.m_vecs.push_back(m_vecs[i]); + ++i; + } + else if (m_indices[i] > other.m_indices[j]) + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(other.m_vecs[j]); + ++j; + } + else + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(m_vecs[i] + other.m_vecs[j]); + ++i; ++j; + } + } + while (i < m_indices.size()) + { + ret.m_indices.push_back(m_indices[i]); + ret.m_vecs.push_back(m_vecs[i]); + ++i; + } + while (j < other.m_indices.size()) + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(other.m_vecs[j]); + ++j; + } + ret.simplify(); + return ret; + } + + btReducedVector operator-() + { + btReducedVector ret(m_sz); + for (int i = 0; i < m_indices.size(); ++i) + { + ret.m_indices.push_back(m_indices[i]); + ret.m_vecs.push_back(-m_vecs[i]); + } + ret.simplify(); + return ret; + } + + btReducedVector operator-(const btReducedVector& other) + { + btReducedVector ret(m_sz); + int i=0, j=0; + while (i < m_indices.size() && j < other.m_indices.size()) + { + if (m_indices[i] < other.m_indices[j]) + { + ret.m_indices.push_back(m_indices[i]); + ret.m_vecs.push_back(m_vecs[i]); + ++i; + } + else if (m_indices[i] > other.m_indices[j]) + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(-other.m_vecs[j]); + ++j; + } + else + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(m_vecs[i] - other.m_vecs[j]); + ++i; ++j; + } + } + while (i < m_indices.size()) + { + ret.m_indices.push_back(m_indices[i]); + ret.m_vecs.push_back(m_vecs[i]); + ++i; + } + while (j < other.m_indices.size()) + { + ret.m_indices.push_back(other.m_indices[j]); + ret.m_vecs.push_back(-other.m_vecs[j]); + ++j; + } + ret.simplify(); + return ret; + } + + bool operator==(const btReducedVector& other) const + { + if (m_sz != other.m_sz) + return false; + if (m_indices.size() != other.m_indices.size()) + return false; + for (int i = 0; i < m_indices.size(); ++i) + { + if (m_indices[i] != other.m_indices[i] || m_vecs[i] != other.m_vecs[i]) + { + return false; + } + } + return true; + } + + bool operator!=(const btReducedVector& other) const + { + return !(*this == other); + } + + btReducedVector& operator=(const btReducedVector& other) + { + if (this == &other) + { + return *this; + } + m_sz = other.m_sz; + m_indices.copyFromArray(other.m_indices); + m_vecs.copyFromArray(other.m_vecs); + return *this; + } + + btScalar dot(const btReducedVector& other) const + { + btScalar ret = 0; + int j = 0; + for (int i = 0; i < m_indices.size(); ++i) + { + while (j < other.m_indices.size() && other.m_indices[j] < m_indices[i]) + { + ++j; + } + if (j < other.m_indices.size() && other.m_indices[j] == m_indices[i]) + { + ret += m_vecs[i].dot(other.m_vecs[j]); +// ++j; + } + } + return ret; + } + + btScalar dot(const btAlignedObjectArray<btVector3>& other) const + { + btScalar ret = 0; + for (int i = 0; i < m_indices.size(); ++i) + { + ret += m_vecs[i].dot(other[m_indices[i]]); + } + return ret; + } + + btScalar length2() const + { + return this->dot(*this); + } + + void normalize(); + + // returns the projection of this onto other + btReducedVector proj(const btReducedVector& other) const; + + bool testAdd() const; + + bool testMinus() const; + + bool testDot() const; + + bool testMultiply() const; + + void test() const; + + void print() const + { + for (int i = 0; i < m_indices.size(); ++i) + { + printf("%d: (%f, %f, %f)/", m_indices[i], m_vecs[i][0],m_vecs[i][1],m_vecs[i][2]); + } + printf("\n"); + } + + + void sort() + { + std::vector<TwoInts> tuples; + for (int i = 0; i < m_indices.size(); ++i) + { + TwoInts ti; + ti.a = i; + ti.b = m_indices[i]; + tuples.push_back(ti); + } + std::sort(tuples.begin(), tuples.end()); + btAlignedObjectArray<int> new_indices; + btAlignedObjectArray<btVector3> new_vecs; + for (int i = 0; i < tuples.size(); ++i) + { + new_indices.push_back(tuples[i].b); + new_vecs.push_back(m_vecs[tuples[i].a]); + } + m_indices = new_indices; + m_vecs = new_vecs; + } +}; + +SIMD_FORCE_INLINE btReducedVector operator*(const btReducedVector& v, btScalar s) +{ + btReducedVector ret(v.m_sz); + for (int i = 0; i < v.m_indices.size(); ++i) + { + ret.m_indices.push_back(v.m_indices[i]); + ret.m_vecs.push_back(s*v.m_vecs[i]); + } + ret.simplify(); + return ret; +} + +SIMD_FORCE_INLINE btReducedVector operator*(btScalar s, const btReducedVector& v) +{ + return v*s; +} + +SIMD_FORCE_INLINE btReducedVector operator/(const btReducedVector& v, btScalar s) +{ + return v * (1.0/s); +} + +SIMD_FORCE_INLINE btReducedVector& operator/=(btReducedVector& v, btScalar s) +{ + v = v/s; + return v; +} + +SIMD_FORCE_INLINE btReducedVector& operator+=(btReducedVector& v1, const btReducedVector& v2) +{ + v1 = v1+v2; + return v1; +} + +SIMD_FORCE_INLINE btReducedVector& operator-=(btReducedVector& v1, const btReducedVector& v2) +{ + v1 = v1-v2; + return v1; +} + +#endif /* btReducedVectors_h */ diff --git a/thirdparty/bullet/btBulletCollisionAll.cpp b/thirdparty/bullet/btBulletCollisionAll.cpp index 2851fb3b73..4a3ec8dd6f 100644 --- a/thirdparty/bullet/btBulletCollisionAll.cpp +++ b/thirdparty/bullet/btBulletCollisionAll.cpp @@ -23,6 +23,7 @@ #include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp" #include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp" #include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp" #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp" #include "BulletCollision/CollisionDispatch/btCollisionObject.cpp" diff --git a/thirdparty/bullet/btLinearMathAll.cpp b/thirdparty/bullet/btLinearMathAll.cpp index 808f412803..d05a19e630 100644 --- a/thirdparty/bullet/btLinearMathAll.cpp +++ b/thirdparty/bullet/btLinearMathAll.cpp @@ -8,6 +8,7 @@ #include "LinearMath/btConvexHullComputer.cpp" #include "LinearMath/btQuickprof.cpp" #include "LinearMath/btThreads.cpp" +#include "LinearMath/btReducedVector.cpp" #include "LinearMath/TaskScheduler/btTaskScheduler.cpp" #include "LinearMath/TaskScheduler/btThreadSupportPosix.cpp" #include "LinearMath/TaskScheduler/btThreadSupportWin32.cpp" diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp index 62fbd1b72d..257d0b7574 100644 --- a/thirdparty/jpeg-compressor/jpgd.cpp +++ b/thirdparty/jpeg-compressor/jpgd.cpp @@ -1,27 +1,55 @@ -// jpgd.cpp - C++ class for JPEG decompression. -// Public domain, Rich Geldreich <richgel99@gmail.com> +// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <richgel99@gmail.com> between 1994-2020. +// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// Supports box and linear chroma upsampling. +// +// Released under two licenses. You are free to choose which license you want: +// License 1: +// Public Domain +// +// License 2: +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // Alex Evans: Linear memory allocator (taken from jpge.h). -// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless) +// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings +// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings. // -// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// Important: +// #define JPGD_USE_SSE2 to 0 to completely disable SSE2 usage. // -// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling. -// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain" -// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html - #include "jpgd.h" #include <string.h> - +#include <algorithm> #include <assert.h> -#define JPGD_ASSERT(x) assert(x) #ifdef _MSC_VER #pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable #endif -// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling). -// This is slower, but results in higher quality on images with highly saturated colors. -#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1 +#ifndef JPGD_USE_SSE2 + + #if defined(__GNUC__) + + #if (defined(__x86_64__) || defined(_M_X64)) + #if defined(__SSE2__) + #define JPGD_USE_SSE2 (1) + #endif + #endif + + #else + #define JPGD_USE_SSE2 (1) + #endif + +#endif #define JPGD_TRUE (1) #define JPGD_FALSE (0) @@ -29,28 +57,28 @@ #define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b)) #define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b)) -// TODO: Move to header and use these constants when declaring the arrays. -#define JPGD_HUFF_TREE_MAX_LENGTH 512 -#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256 - namespace jpgd { -static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); } -static inline void jpgd_free(void *p) { free(p); } + static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); } + static inline void jpgd_free(void* p) { free(p); } -// DCT coefficients are stored in this sequence. -static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; + // DCT coefficients are stored in this sequence. + static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; -enum JPEG_MARKER -{ - M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, - M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, - M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, - M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, - M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 -}; + enum JPEG_MARKER + { + M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, + M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, + M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, + M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, + M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 + }; -enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + +#if JPGD_USE_SSE2 +#include "jpgd_idct.h" +#endif #define CONST_BITS 13 #define PASS1_BITS 2 @@ -76,3130 +104,3182 @@ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, #define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i)) -// Compiler creates a fast path 1D IDCT for X non-zero columns -template <int NONZERO_COLS> -struct Row -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { - // ACCESS_COL() will be optimized at compile time to either an array access, or 0. - #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) - - const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); - - const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS; - const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS; - - const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; - - const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); - - const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; - const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); - - const int az1 = MULTIPLY(bz1, - FIX_0_899976223); - const int az2 = MULTIPLY(bz2, - FIX_2_562915447); - const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; - const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; - - const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; - const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; - const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; - const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; - - pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS); - pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS); - pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS); - pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS); - pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS); - pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS); - pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS); - pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS); - } -}; - -template <> -struct Row<0> -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { -#ifdef _MSC_VER - pTemp; pSrc; + static inline int left_shifti(int val, uint32_t bits) + { + return static_cast<int>(static_cast<uint32_t>(val) << bits); + } + + // Compiler creates a fast path 1D IDCT for X non-zero columns + template <int NONZERO_COLS> + struct Row + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + // ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0. +#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) + + const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS); + pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS); + pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS); + pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS); + pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS); + pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS); + pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS); + pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS); + } + }; + + template <> + struct Row<0> + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + (void)pTemp; + (void)pSrc; + } + }; + + template <> + struct Row<1> + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + const int dcval = left_shifti(pSrc[0], PASS1_BITS); + + pTemp[0] = dcval; + pTemp[1] = dcval; + pTemp[2] = dcval; + pTemp[3] = dcval; + pTemp[4] = dcval; + pTemp[5] = dcval; + pTemp[6] = dcval; + pTemp[7] = dcval; + } + }; + + // Compiler creates a fast path 1D IDCT for X non-zero rows + template <int NONZERO_ROWS> + struct Col + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. +#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) + + const int z2 = ACCESS_ROW(2); + const int z3 = ACCESS_ROW(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 0] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 7] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 1] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 6] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 2] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 5] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 3] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 4] = (uint8)CLAMP(i); + } + }; + + template <> + struct Col<1> + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3); + const uint8 dcval_clamped = (uint8)CLAMP(dcval); + pDst_ptr[0 * 8] = dcval_clamped; + pDst_ptr[1 * 8] = dcval_clamped; + pDst_ptr[2 * 8] = dcval_clamped; + pDst_ptr[3 * 8] = dcval_clamped; + pDst_ptr[4 * 8] = dcval_clamped; + pDst_ptr[5 * 8] = dcval_clamped; + pDst_ptr[6 * 8] = dcval_clamped; + pDst_ptr[7 * 8] = dcval_clamped; + } + }; + + static const uint8 s_idct_row_table[] = + { + 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, + 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, + 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, + 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, + 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, + 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, + 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, + 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, + }; + + static const uint8 s_idct_col_table[] = + { + 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // Scalar "fast pathing" IDCT. + static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd) + { + (void)use_simd; + + assert(block_max_zag >= 1); + assert(block_max_zag <= 64); + + if (block_max_zag <= 1) + { + int k = ((pSrc_ptr[0] + 4) >> 3) + 128; + k = CLAMP(k); + k = k | (k << 8); + k = k | (k << 16); + + for (int i = 8; i > 0; i--) + { + *(int*)&pDst_ptr[0] = k; + *(int*)&pDst_ptr[4] = k; + pDst_ptr += 8; + } + return; + } + +#if JPGD_USE_SSE2 + if (use_simd) + { + assert((((uintptr_t)pSrc_ptr) & 15) == 0); + assert((((uintptr_t)pDst_ptr) & 15) == 0); + idctSSEShortU8(pSrc_ptr, pDst_ptr); + return; + } #endif - } -}; - -template <> -struct Row<1> -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { - const int dcval = (pSrc[0] << PASS1_BITS); - - pTemp[0] = dcval; - pTemp[1] = dcval; - pTemp[2] = dcval; - pTemp[3] = dcval; - pTemp[4] = dcval; - pTemp[5] = dcval; - pTemp[6] = dcval; - pTemp[7] = dcval; - } -}; - -// Compiler creates a fast path 1D IDCT for X non-zero rows -template <int NONZERO_ROWS> -struct Col -{ - static void idct(uint8* pDst_ptr, const int* pTemp) - { - // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. - #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) - - const int z2 = ACCESS_ROW(2); - const int z3 = ACCESS_ROW(6); - - const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS; - const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS; - - const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; - - const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); - - const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; - const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); - - const int az1 = MULTIPLY(bz1, - FIX_0_899976223); - const int az2 = MULTIPLY(bz2, - FIX_2_562915447); - const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; - const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; - - const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; - const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; - const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; - const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; - - int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*0] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*7] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*1] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*6] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*2] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*5] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*3] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*4] = (uint8)CLAMP(i); - } -}; - -template <> -struct Col<1> -{ - static void idct(uint8* pDst_ptr, const int* pTemp) - { - int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3); - const uint8 dcval_clamped = (uint8)CLAMP(dcval); - pDst_ptr[0*8] = dcval_clamped; - pDst_ptr[1*8] = dcval_clamped; - pDst_ptr[2*8] = dcval_clamped; - pDst_ptr[3*8] = dcval_clamped; - pDst_ptr[4*8] = dcval_clamped; - pDst_ptr[5*8] = dcval_clamped; - pDst_ptr[6*8] = dcval_clamped; - pDst_ptr[7*8] = dcval_clamped; - } -}; - -static const uint8 s_idct_row_table[] = -{ - 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, - 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, - 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, - 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, - 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, - 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, - 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, - 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, -}; - -static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; - -void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag) -{ - JPGD_ASSERT(block_max_zag >= 1); - JPGD_ASSERT(block_max_zag <= 64); - - if (block_max_zag <= 1) - { - int k = ((pSrc_ptr[0] + 4) >> 3) + 128; - k = CLAMP(k); - k = k | (k<<8); - k = k | (k<<16); - - for (int i = 8; i > 0; i--) - { - *(int*)&pDst_ptr[0] = k; - *(int*)&pDst_ptr[4] = k; - pDst_ptr += 8; - } - return; - } - - int temp[64]; - - const jpgd_block_t* pSrc = pSrc_ptr; - int* pTemp = temp; - - const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; - int i; - for (i = 8; i > 0; i--, pRow_tab++) - { - switch (*pRow_tab) - { - case 0: Row<0>::idct(pTemp, pSrc); break; - case 1: Row<1>::idct(pTemp, pSrc); break; - case 2: Row<2>::idct(pTemp, pSrc); break; - case 3: Row<3>::idct(pTemp, pSrc); break; - case 4: Row<4>::idct(pTemp, pSrc); break; - case 5: Row<5>::idct(pTemp, pSrc); break; - case 6: Row<6>::idct(pTemp, pSrc); break; - case 7: Row<7>::idct(pTemp, pSrc); break; - case 8: Row<8>::idct(pTemp, pSrc); break; - } - - pSrc += 8; - pTemp += 8; - } - - pTemp = temp; - - const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; - for (i = 8; i > 0; i--) - { - switch (nonzero_rows) - { - case 1: Col<1>::idct(pDst_ptr, pTemp); break; - case 2: Col<2>::idct(pDst_ptr, pTemp); break; - case 3: Col<3>::idct(pDst_ptr, pTemp); break; - case 4: Col<4>::idct(pDst_ptr, pTemp); break; - case 5: Col<5>::idct(pDst_ptr, pTemp); break; - case 6: Col<6>::idct(pDst_ptr, pTemp); break; - case 7: Col<7>::idct(pDst_ptr, pTemp); break; - case 8: Col<8>::idct(pDst_ptr, pTemp); break; - } - - pTemp++; - pDst_ptr++; - } -} - -void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr) -{ - int temp[64]; - int* pTemp = temp; - const jpgd_block_t* pSrc = pSrc_ptr; - - for (int i = 4; i > 0; i--) - { - Row<4>::idct(pTemp, pSrc); - pSrc += 8; - pTemp += 8; - } - - pTemp = temp; - for (int i = 8; i > 0; i--) - { - Col<4>::idct(pDst_ptr, pTemp); - pTemp++; - pDst_ptr++; - } -} - -// Retrieve one character from the input stream. -inline uint jpeg_decoder::get_char() -{ - // Any bytes remaining in buffer? - if (!m_in_buf_left) - { - // Try to get more bytes. - prep_in_buffer(); - // Still nothing to get? - if (!m_in_buf_left) - { - // Pad the end of the stream with 0xFF 0xD9 (EOI marker) - int t = m_tem_flag; - m_tem_flag ^= 1; - if (t) - return 0xD9; - else - return 0xFF; - } - } - - uint c = *m_pIn_buf_ofs++; - m_in_buf_left--; - - return c; -} - -// Same as previous method, except can indicate if the character is a pad character or not. -inline uint jpeg_decoder::get_char(bool *pPadding_flag) -{ - if (!m_in_buf_left) - { - prep_in_buffer(); - if (!m_in_buf_left) - { - *pPadding_flag = true; - int t = m_tem_flag; - m_tem_flag ^= 1; - if (t) - return 0xD9; - else - return 0xFF; - } - } - - *pPadding_flag = false; - - uint c = *m_pIn_buf_ofs++; - m_in_buf_left--; - - return c; -} - -// Inserts a previously retrieved character back into the input buffer. -inline void jpeg_decoder::stuff_char(uint8 q) -{ - *(--m_pIn_buf_ofs) = q; - m_in_buf_left++; -} - -// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. -inline uint8 jpeg_decoder::get_octet() -{ - bool padding_flag; - int c = get_char(&padding_flag); - - if (c == 0xFF) - { - if (padding_flag) - return 0xFF; - - c = get_char(&padding_flag); - if (padding_flag) - { - stuff_char(0xFF); - return 0xFF; - } - - if (c == 0x00) - return 0xFF; - else - { - stuff_char(static_cast<uint8>(c)); - stuff_char(0xFF); - return 0xFF; - } - } - - return static_cast<uint8>(c); -} - -// Retrieves a variable number of bits from the input stream. Does not recognize markers. -inline uint jpeg_decoder::get_bits(int num_bits) -{ - if (!num_bits) - return 0; - - uint i = m_bit_buf >> (32 - num_bits); - - if ((m_bits_left -= num_bits) <= 0) - { - m_bit_buf <<= (num_bits += m_bits_left); - - uint c1 = get_char(); - uint c2 = get_char(); - m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; - - m_bit_buf <<= -m_bits_left; - - m_bits_left += 16; - - JPGD_ASSERT(m_bits_left >= 0); - } - else - m_bit_buf <<= num_bits; - - return i; -} - -// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. -inline uint jpeg_decoder::get_bits_no_markers(int num_bits) -{ - if (!num_bits) - return 0; - - uint i = m_bit_buf >> (32 - num_bits); - - if ((m_bits_left -= num_bits) <= 0) - { - m_bit_buf <<= (num_bits += m_bits_left); - - if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) - { - uint c1 = get_octet(); - uint c2 = get_octet(); - m_bit_buf |= (c1 << 8) | c2; - } - else - { - m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; - m_in_buf_left -= 2; - m_pIn_buf_ofs += 2; - } - - m_bit_buf <<= -m_bits_left; - - m_bits_left += 16; - - JPGD_ASSERT(m_bits_left >= 0); - } - else - m_bit_buf <<= num_bits; - - return i; -} - -// Decodes a Huffman encoded symbol. -inline int jpeg_decoder::huff_decode(huff_tables *pH) -{ - JPGD_ASSERT(pH); - - int symbol; - // Check first 8-bits: do we have a complete symbol? - if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) - { - // Decode more bits, use a tree traversal to find symbol. - int ofs = 23; - do - { - unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - symbol = pH->tree[idx]; - ofs--; - } while (symbol < 0); - - get_bits_no_markers(8 + (23 - ofs)); - } - else - { - JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - get_bits_no_markers(pH->code_size[symbol]); - } - - return symbol; -} - -// Decodes a Huffman encoded symbol. -inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits) -{ - int symbol; - - JPGD_ASSERT(pH); - - // Check first 8-bits: do we have a complete symbol? - if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) - { - // Use a tree traversal to find symbol. - int ofs = 23; - do - { - unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - symbol = pH->tree[idx]; - ofs--; - } while (symbol < 0); - - get_bits_no_markers(8 + (23 - ofs)); - - extra_bits = get_bits_no_markers(symbol & 0xF); - } - else - { - JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0)); - - if (symbol & 0x8000) - { - get_bits_no_markers((symbol >> 8) & 31); - extra_bits = symbol >> 16; - } - else - { - int code_size = (symbol >> 8) & 31; - int num_extra_bits = symbol & 0xF; - int bits = code_size + num_extra_bits; - if (bits <= (m_bits_left + 16)) - extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); - else - { - get_bits_no_markers(code_size); - extra_bits = get_bits_no_markers(num_extra_bits); - } - } - - symbol &= 0xFF; - } - - return symbol; -} - -// Tables and macro used to fully decode the DPCM differences. -static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; -static const int s_extend_offset[16] = { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; -static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) }; -// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this) + + int temp[64]; + + const jpgd_block_coeff_t* pSrc = pSrc_ptr; + int* pTemp = temp; + + const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; + int i; + for (i = 8; i > 0; i--, pRow_tab++) + { + switch (*pRow_tab) + { + case 0: Row<0>::idct(pTemp, pSrc); break; + case 1: Row<1>::idct(pTemp, pSrc); break; + case 2: Row<2>::idct(pTemp, pSrc); break; + case 3: Row<3>::idct(pTemp, pSrc); break; + case 4: Row<4>::idct(pTemp, pSrc); break; + case 5: Row<5>::idct(pTemp, pSrc); break; + case 6: Row<6>::idct(pTemp, pSrc); break; + case 7: Row<7>::idct(pTemp, pSrc); break; + case 8: Row<8>::idct(pTemp, pSrc); break; + } + + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; + for (i = 8; i > 0; i--) + { + switch (nonzero_rows) + { + case 1: Col<1>::idct(pDst_ptr, pTemp); break; + case 2: Col<2>::idct(pDst_ptr, pTemp); break; + case 3: Col<3>::idct(pDst_ptr, pTemp); break; + case 4: Col<4>::idct(pDst_ptr, pTemp); break; + case 5: Col<5>::idct(pDst_ptr, pTemp); break; + case 6: Col<6>::idct(pDst_ptr, pTemp); break; + case 7: Col<7>::idct(pDst_ptr, pTemp); break; + case 8: Col<8>::idct(pDst_ptr, pTemp); break; + } + + pTemp++; + pDst_ptr++; + } + } + + // Retrieve one character from the input stream. + inline uint jpeg_decoder::get_char() + { + // Any bytes remaining in buffer? + if (!m_in_buf_left) + { + // Try to get more bytes. + prep_in_buffer(); + // Still nothing to get? + if (!m_in_buf_left) + { + // Pad the end of the stream with 0xFF 0xD9 (EOI marker) + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Same as previous method, except can indicate if the character is a pad character or not. + inline uint jpeg_decoder::get_char(bool* pPadding_flag) + { + if (!m_in_buf_left) + { + prep_in_buffer(); + if (!m_in_buf_left) + { + *pPadding_flag = true; + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + *pPadding_flag = false; + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Inserts a previously retrieved character back into the input buffer. + inline void jpeg_decoder::stuff_char(uint8 q) + { + // This could write before the input buffer, but we've placed another array there. + *(--m_pIn_buf_ofs) = q; + m_in_buf_left++; + } + + // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. + inline uint8 jpeg_decoder::get_octet() + { + bool padding_flag; + int c = get_char(&padding_flag); + + if (c == 0xFF) + { + if (padding_flag) + return 0xFF; + + c = get_char(&padding_flag); + if (padding_flag) + { + stuff_char(0xFF); + return 0xFF; + } + + if (c == 0x00) + return 0xFF; + else + { + stuff_char(static_cast<uint8>(c)); + stuff_char(0xFF); + return 0xFF; + } + } + + return static_cast<uint8>(c); + } + + // Retrieves a variable number of bits from the input stream. Does not recognize markers. + inline uint jpeg_decoder::get_bits(int num_bits) + { + if (!num_bits) + return 0; + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + uint c1 = get_char(); + uint c2 = get_char(); + m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. + inline uint jpeg_decoder::get_bits_no_markers(int num_bits) + { + if (!num_bits) + return 0; + + assert(num_bits <= 16); + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) + { + uint c1 = get_octet(); + uint c2 = get_octet(); + m_bit_buf |= (c1 << 8) | c2; + } + else + { + m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; + m_in_buf_left -= 2; + m_pIn_buf_ofs += 2; + } + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH) + { + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + int symbol; + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) + { + // Decode more bits, use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + } + else + { + assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + get_bits_no_markers(pH->code_size[symbol]); + } + + return symbol; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits) + { + int symbol; + + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) + { + // Use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + + extra_bits = get_bits_no_markers(symbol & 0xF); + } + else + { + if (symbol & 0x8000) + { + //get_bits_no_markers((symbol >> 8) & 31); + assert(((symbol >> 8) & 31) <= 15); + get_bits_no_markers((symbol >> 8) & 15); + extra_bits = symbol >> 16; + } + else + { + int code_size = (symbol >> 8) & 31; + int num_extra_bits = symbol & 0xF; + int bits = code_size + num_extra_bits; + + if (bits <= 16) + extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); + else + { + get_bits_no_markers(code_size); + extra_bits = get_bits_no_markers(num_extra_bits); + } + } + + symbol &= 0xFF; + } + + return symbol; + } + + // Tables and macro used to fully decode the DPCM differences. + static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 }; + //static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) }; + #define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) -// Clamps a value between 0-255. -inline uint8 jpeg_decoder::clamp(int i) -{ - if (static_cast<uint>(i) > 255) - i = (((~i) >> 31) & 0xFF); - - return static_cast<uint8>(i); -} - -namespace DCT_Upsample -{ - struct Matrix44 - { - typedef int Element_Type; - enum { NUM_ROWS = 4, NUM_COLS = 4 }; - - Element_Type v[NUM_ROWS][NUM_COLS]; - - inline int rows() const { return NUM_ROWS; } - inline int cols() const { return NUM_COLS; } - - inline const Element_Type & at(int r, int c) const { return v[r][c]; } - inline Element_Type & at(int r, int c) { return v[r][c]; } - - inline Matrix44() { } - - inline Matrix44& operator += (const Matrix44& a) - { - for (int r = 0; r < NUM_ROWS; r++) - { - at(r, 0) += a.at(r, 0); - at(r, 1) += a.at(r, 1); - at(r, 2) += a.at(r, 2); - at(r, 3) += a.at(r, 3); - } - return *this; - } - - inline Matrix44& operator -= (const Matrix44& a) - { - for (int r = 0; r < NUM_ROWS; r++) - { - at(r, 0) -= a.at(r, 0); - at(r, 1) -= a.at(r, 1); - at(r, 2) -= a.at(r, 2); - at(r, 3) -= a.at(r, 3); - } - return *this; - } - - friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b) - { - Matrix44 ret; - for (int r = 0; r < NUM_ROWS; r++) - { - ret.at(r, 0) = a.at(r, 0) + b.at(r, 0); - ret.at(r, 1) = a.at(r, 1) + b.at(r, 1); - ret.at(r, 2) = a.at(r, 2) + b.at(r, 2); - ret.at(r, 3) = a.at(r, 3) + b.at(r, 3); - } - return ret; - } - - friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b) - { - Matrix44 ret; - for (int r = 0; r < NUM_ROWS; r++) - { - ret.at(r, 0) = a.at(r, 0) - b.at(r, 0); - ret.at(r, 1) = a.at(r, 1) - b.at(r, 1); - ret.at(r, 2) = a.at(r, 2) - b.at(r, 2); - ret.at(r, 3) = a.at(r, 3) - b.at(r, 3); - } - return ret; - } - - static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) - { - for (int r = 0; r < 4; r++) - { - pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0)); - pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1)); - pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2)); - pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3)); - } - } - - static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) - { - for (int r = 0; r < 4; r++) - { - pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0)); - pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1)); - pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2)); - pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3)); - } - } - }; - - const int FRACT_BITS = 10; - const int SCALE = 1 << FRACT_BITS; - - typedef int Temp_Type; - #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS) - #define F(i) ((int)((i) * SCALE + .5f)) - - // Any decent C++ compiler will optimize this at compile time to a 0, or an array access. - #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8]) - - // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix - template<int NUM_ROWS, int NUM_COLS> - struct P_Q - { - static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc) - { - // 4x8 = 4x8 times 8x8, matrix 0 is constant - const Temp_Type X000 = AT(0, 0); - const Temp_Type X001 = AT(0, 1); - const Temp_Type X002 = AT(0, 2); - const Temp_Type X003 = AT(0, 3); - const Temp_Type X004 = AT(0, 4); - const Temp_Type X005 = AT(0, 5); - const Temp_Type X006 = AT(0, 6); - const Temp_Type X007 = AT(0, 7); - const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0)); - const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1)); - const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2)); - const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3)); - const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4)); - const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5)); - const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6)); - const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7)); - const Temp_Type X020 = AT(4, 0); - const Temp_Type X021 = AT(4, 1); - const Temp_Type X022 = AT(4, 2); - const Temp_Type X023 = AT(4, 3); - const Temp_Type X024 = AT(4, 4); - const Temp_Type X025 = AT(4, 5); - const Temp_Type X026 = AT(4, 6); - const Temp_Type X027 = AT(4, 7); - const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0)); - const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1)); - const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2)); - const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3)); - const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4)); - const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5)); - const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6)); - const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7)); - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - P.at(0, 0) = X000; - P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f)); - P.at(0, 2) = X004; - P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f)); - P.at(1, 0) = X010; - P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f)); - P.at(1, 2) = X014; - P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f)); - P.at(2, 0) = X020; - P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f)); - P.at(2, 2) = X024; - P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f)); - P.at(3, 0) = X030; - P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f)); - P.at(3, 2) = X034; - P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f)); - // 40 muls 24 adds - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f)); - Q.at(0, 1) = X002; - Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f)); - Q.at(0, 3) = X006; - Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f)); - Q.at(1, 1) = X012; - Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f)); - Q.at(1, 3) = X016; - Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f)); - Q.at(2, 1) = X022; - Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f)); - Q.at(2, 3) = X026; - Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f)); - Q.at(3, 1) = X032; - Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f)); - Q.at(3, 3) = X036; - // 40 muls 24 adds - } - }; - - template<int NUM_ROWS, int NUM_COLS> - struct R_S - { - static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc) - { - // 4x8 = 4x8 times 8x8, matrix 0 is constant - const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0)); - const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1)); - const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2)); - const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3)); - const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4)); - const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5)); - const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6)); - const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7)); - const Temp_Type X110 = AT(2, 0); - const Temp_Type X111 = AT(2, 1); - const Temp_Type X112 = AT(2, 2); - const Temp_Type X113 = AT(2, 3); - const Temp_Type X114 = AT(2, 4); - const Temp_Type X115 = AT(2, 5); - const Temp_Type X116 = AT(2, 6); - const Temp_Type X117 = AT(2, 7); - const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0)); - const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1)); - const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2)); - const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3)); - const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4)); - const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5)); - const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6)); - const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7)); - const Temp_Type X130 = AT(6, 0); - const Temp_Type X131 = AT(6, 1); - const Temp_Type X132 = AT(6, 2); - const Temp_Type X133 = AT(6, 3); - const Temp_Type X134 = AT(6, 4); - const Temp_Type X135 = AT(6, 5); - const Temp_Type X136 = AT(6, 6); - const Temp_Type X137 = AT(6, 7); - // 80 muls 48 adds - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - R.at(0, 0) = X100; - R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f)); - R.at(0, 2) = X104; - R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f)); - R.at(1, 0) = X110; - R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f)); - R.at(1, 2) = X114; - R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f)); - R.at(2, 0) = X120; - R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f)); - R.at(2, 2) = X124; - R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f)); - R.at(3, 0) = X130; - R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f)); - R.at(3, 2) = X134; - R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f)); - // 40 muls 24 adds - // 4x4 = 4x8 times 8x4, matrix 1 is constant - S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f)); - S.at(0, 1) = X102; - S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f)); - S.at(0, 3) = X106; - S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f)); - S.at(1, 1) = X112; - S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f)); - S.at(1, 3) = X116; - S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f)); - S.at(2, 1) = X122; - S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f)); - S.at(2, 3) = X126; - S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f)); - S.at(3, 1) = X132; - S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f)); - S.at(3, 3) = X136; - // 40 muls 24 adds - } - }; -} // end namespace DCT_Upsample - -// Unconditionally frees all allocated m_blocks. -void jpeg_decoder::free_all_blocks() -{ - m_pStream = NULL; - for (mem_block *b = m_pMem_blocks; b; ) - { - mem_block *n = b->m_pNext; - jpgd_free(b); - b = n; - } - m_pMem_blocks = NULL; -} - -// This method handles all errors. It will never return. -// It could easily be changed to use C++ exceptions. -JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) -{ - m_error_code = status; - free_all_blocks(); - longjmp(m_jmp_state, status); -} - -void *jpeg_decoder::alloc(size_t nSize, bool zero) -{ - nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; - char *rv = NULL; - for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext) - { - if ((b->m_used_count + nSize) <= b->m_size) - { - rv = b->m_data + b->m_used_count; - b->m_used_count += nSize; - break; - } - } - if (!rv) - { - int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); - mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); - if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); } - b->m_pNext = m_pMem_blocks; m_pMem_blocks = b; - b->m_used_count = nSize; - b->m_size = capacity; - rv = b->m_data; - } - if (zero) memset(rv, 0, nSize); - return rv; -} - -void jpeg_decoder::word_clear(void *p, uint16 c, uint n) -{ - uint8 *pD = (uint8*)p; - const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; - while (n) - { - pD[0] = l; pD[1] = h; pD += 2; - n--; - } -} - -// Refill the input buffer. -// This method will sit in a loop until (A) the buffer is full or (B) -// the stream's read() method reports and end of file condition. -void jpeg_decoder::prep_in_buffer() -{ - m_in_buf_left = 0; - m_pIn_buf_ofs = m_in_buf; - - if (m_eof_flag) - return; - - do - { - int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); - if (bytes_read == -1) - stop_decoding(JPGD_STREAM_READ); - - m_in_buf_left += bytes_read; - } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); - - m_total_bytes_read += m_in_buf_left; - - // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). - // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) - word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); -} - -// Read a Huffman code table. -void jpeg_decoder::read_dht_marker() -{ - int i, index, count; - uint8 huff_num[17]; - uint8 huff_val[256]; - - uint num_left = get_bits(16); - - if (num_left < 2) - stop_decoding(JPGD_BAD_DHT_MARKER); - - num_left -= 2; - - while (num_left) - { - index = get_bits(8); - - huff_num[0] = 0; - - count = 0; - - for (i = 1; i <= 16; i++) - { - huff_num[i] = static_cast<uint8>(get_bits(8)); - count += huff_num[i]; - } - - if (count > 255) - stop_decoding(JPGD_BAD_DHT_COUNTS); - - for (i = 0; i < count; i++) - huff_val[i] = static_cast<uint8>(get_bits(8)); + // Unconditionally frees all allocated m_blocks. + void jpeg_decoder::free_all_blocks() + { + m_pStream = nullptr; + for (mem_block* b = m_pMem_blocks; b; ) + { + mem_block* n = b->m_pNext; + jpgd_free(b); + b = n; + } + m_pMem_blocks = nullptr; + } + + // This method handles all errors. It will never return. + // It could easily be changed to use C++ exceptions. + JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) + { + m_error_code = status; + free_all_blocks(); + longjmp(m_jmp_state, status); + } + + void* jpeg_decoder::alloc(size_t nSize, bool zero) + { + nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; + char* rv = nullptr; + for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext) + { + if ((b->m_used_count + nSize) <= b->m_size) + { + rv = b->m_data + b->m_used_count; + b->m_used_count += nSize; + break; + } + } + if (!rv) + { + int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); + mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); + if (!b) + { + stop_decoding(JPGD_NOTENOUGHMEM); + } + + b->m_pNext = m_pMem_blocks; + m_pMem_blocks = b; + b->m_used_count = nSize; + b->m_size = capacity; + rv = b->m_data; + } + if (zero) memset(rv, 0, nSize); + return rv; + } + + void* jpeg_decoder::alloc_aligned(size_t nSize, uint32_t align, bool zero) + { + assert((align >= 1U) && ((align & (align - 1U)) == 0U)); + void *p = alloc(nSize + align - 1U, zero); + p = (void *)( ((uintptr_t)p + (align - 1U)) & ~((uintptr_t)(align - 1U)) ); + return p; + } + + void jpeg_decoder::word_clear(void* p, uint16 c, uint n) + { + uint8* pD = (uint8*)p; + const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; + while (n) + { + pD[0] = l; + pD[1] = h; + pD += 2; + n--; + } + } + + // Refill the input buffer. + // This method will sit in a loop until (A) the buffer is full or (B) + // the stream's read() method reports and end of file condition. + void jpeg_decoder::prep_in_buffer() + { + m_in_buf_left = 0; + m_pIn_buf_ofs = m_in_buf; + + if (m_eof_flag) + return; + + do + { + int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); + if (bytes_read == -1) + stop_decoding(JPGD_STREAM_READ); + + m_in_buf_left += bytes_read; + } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); + + m_total_bytes_read += m_in_buf_left; + + // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). + // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) + word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); + } + + // Read a Huffman code table. + void jpeg_decoder::read_dht_marker() + { + int i, index, count; + uint8 huff_num[17]; + uint8 huff_val[256]; + + uint num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= 2; + + while (num_left) + { + index = get_bits(8); + + huff_num[0] = 0; + + count = 0; + + for (i = 1; i <= 16; i++) + { + huff_num[i] = static_cast<uint8>(get_bits(8)); + count += huff_num[i]; + } + + if (count > 255) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + bool symbol_present[256]; + memset(symbol_present, 0, sizeof(symbol_present)); - i = 1 + 16 + count; + for (i = 0; i < count; i++) + { + const int s = get_bits(8); + + // Check for obviously bogus tables. + if (symbol_present[s]) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + huff_val[i] = static_cast<uint8_t>(s); + symbol_present[s] = true; + } - if (num_left < (uint)i) - stop_decoding(JPGD_BAD_DHT_MARKER); + i = 1 + 16 + count; - num_left -= i; + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DHT_MARKER); - if ((index & 0x10) > 0x10) - stop_decoding(JPGD_BAD_DHT_INDEX); + num_left -= i; - index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); + if ((index & 0x10) > 0x10) + stop_decoding(JPGD_BAD_DHT_INDEX); - if (index >= JPGD_MAX_HUFF_TABLES) - stop_decoding(JPGD_BAD_DHT_INDEX); + index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); - if (!m_huff_num[index]) - m_huff_num[index] = (uint8 *)alloc(17); + if (index >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_BAD_DHT_INDEX); - if (!m_huff_val[index]) - m_huff_val[index] = (uint8 *)alloc(256); + if (!m_huff_num[index]) + m_huff_num[index] = (uint8*)alloc(17); - m_huff_ac[index] = (index & 0x10) != 0; - memcpy(m_huff_num[index], huff_num, 17); - memcpy(m_huff_val[index], huff_val, 256); - } -} + if (!m_huff_val[index]) + m_huff_val[index] = (uint8*)alloc(256); -// Read a quantization table. -void jpeg_decoder::read_dqt_marker() -{ - int n, i, prec; - uint num_left; - uint temp; + m_huff_ac[index] = (index & 0x10) != 0; + memcpy(m_huff_num[index], huff_num, 17); + memcpy(m_huff_val[index], huff_val, 256); + } + } - num_left = get_bits(16); + // Read a quantization table. + void jpeg_decoder::read_dqt_marker() + { + int n, i, prec; + uint num_left; + uint temp; - if (num_left < 2) - stop_decoding(JPGD_BAD_DQT_MARKER); + num_left = get_bits(16); - num_left -= 2; + if (num_left < 2) + stop_decoding(JPGD_BAD_DQT_MARKER); - while (num_left) - { - n = get_bits(8); - prec = n >> 4; - n &= 0x0F; + num_left -= 2; - if (n >= JPGD_MAX_QUANT_TABLES) - stop_decoding(JPGD_BAD_DQT_TABLE); + while (num_left) + { + n = get_bits(8); + prec = n >> 4; + n &= 0x0F; - if (!m_quant[n]) - m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t)); + if (n >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_BAD_DQT_TABLE); - // read quantization entries, in zag order - for (i = 0; i < 64; i++) - { - temp = get_bits(8); + if (!m_quant[n]) + m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t)); - if (prec) - temp = (temp << 8) + get_bits(8); + // read quantization entries, in zag order + for (i = 0; i < 64; i++) + { + temp = get_bits(8); - m_quant[n][i] = static_cast<jpgd_quant_t>(temp); - } + if (prec) + temp = (temp << 8) + get_bits(8); - i = 64 + 1; + m_quant[n][i] = static_cast<jpgd_quant_t>(temp); + } - if (prec) - i += 64; + i = 64 + 1; - if (num_left < (uint)i) - stop_decoding(JPGD_BAD_DQT_LENGTH); + if (prec) + i += 64; - num_left -= i; - } -} + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DQT_LENGTH); -// Read the start of frame (SOF) marker. -void jpeg_decoder::read_sof_marker() -{ - int i; - uint num_left; + num_left -= i; + } + } - num_left = get_bits(16); + // Read the start of frame (SOF) marker. + void jpeg_decoder::read_sof_marker() + { + int i; + uint num_left; - if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */ - stop_decoding(JPGD_BAD_PRECISION); + num_left = get_bits(16); - m_image_y_size = get_bits(16); + /* precision: sorry, only 8-bit precision is supported */ + if (get_bits(8) != 8) + stop_decoding(JPGD_BAD_PRECISION); - if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) - stop_decoding(JPGD_BAD_HEIGHT); + m_image_y_size = get_bits(16); - m_image_x_size = get_bits(16); + if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) + stop_decoding(JPGD_BAD_HEIGHT); - if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) - stop_decoding(JPGD_BAD_WIDTH); + m_image_x_size = get_bits(16); - m_comps_in_frame = get_bits(8); + if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) + stop_decoding(JPGD_BAD_WIDTH); - if (m_comps_in_frame > JPGD_MAX_COMPONENTS) - stop_decoding(JPGD_TOO_MANY_COMPONENTS); + m_comps_in_frame = get_bits(8); - if (num_left != (uint)(m_comps_in_frame * 3 + 8)) - stop_decoding(JPGD_BAD_SOF_LENGTH); + if (m_comps_in_frame > JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_TOO_MANY_COMPONENTS); - for (i = 0; i < m_comps_in_frame; i++) - { - m_comp_ident[i] = get_bits(8); - m_comp_h_samp[i] = get_bits(4); - m_comp_v_samp[i] = get_bits(4); - m_comp_quant[i] = get_bits(8); - } -} + if (num_left != (uint)(m_comps_in_frame * 3 + 8)) + stop_decoding(JPGD_BAD_SOF_LENGTH); -// Used to skip unrecognized markers. -void jpeg_decoder::skip_variable_marker() -{ - uint num_left; + for (i = 0; i < m_comps_in_frame; i++) + { + m_comp_ident[i] = get_bits(8); + m_comp_h_samp[i] = get_bits(4); + m_comp_v_samp[i] = get_bits(4); - num_left = get_bits(16); + if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - if (num_left < 2) - stop_decoding(JPGD_BAD_VARIABLE_MARKER); + m_comp_quant[i] = get_bits(8); + if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + } + + // Used to skip unrecognized markers. + void jpeg_decoder::skip_variable_marker() + { + uint num_left; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_VARIABLE_MARKER); + + num_left -= 2; + + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Read a define restart interval (DRI) marker. + void jpeg_decoder::read_dri_marker() + { + if (get_bits(16) != 4) + stop_decoding(JPGD_BAD_DRI_LENGTH); + + m_restart_interval = get_bits(16); + } + + // Read a start of scan (SOS) marker. + void jpeg_decoder::read_sos_marker() + { + uint num_left; + int i, ci, n, c, cc; + + num_left = get_bits(16); + + n = get_bits(8); + + m_comps_in_scan = n; + + num_left -= 3; + + if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN)) + stop_decoding(JPGD_BAD_SOS_LENGTH); + + for (i = 0; i < n; i++) + { + cc = get_bits(8); + c = get_bits(8); + num_left -= 2; + + for (ci = 0; ci < m_comps_in_frame; ci++) + if (cc == m_comp_ident[ci]) + break; + + if (ci >= m_comps_in_frame) + stop_decoding(JPGD_BAD_SOS_COMP_ID); + + if (ci >= JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_DECODE_ERROR); + + m_comp_list[i] = ci; + + m_comp_dc_tab[ci] = (c >> 4) & 15; + m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); + + if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + + m_spectral_start = get_bits(8); + m_spectral_end = get_bits(8); + m_successive_high = get_bits(4); + m_successive_low = get_bits(4); + + if (!m_progressive_flag) + { + m_spectral_start = 0; + m_spectral_end = 63; + } + + num_left -= 3; + + /* read past whatever is num_left */ + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Finds the next marker. + int jpeg_decoder::next_marker() + { + uint c, bytes; + + bytes = 0; + + do + { + do + { + bytes++; + c = get_bits(8); + } while (c != 0xFF); - num_left -= 2; + do + { + c = get_bits(8); + } while (c == 0xFF); + + } while (c == 0); + + // If bytes > 0 here, there where extra bytes before the marker (not good). + + return c; + } + + // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is + // encountered. + int jpeg_decoder::process_markers() + { + int c; + + for (; ; ) + { + c = next_marker(); + + switch (c) + { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + // case M_JPG: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + case M_SOI: + case M_EOI: + case M_SOS: + { + return c; + } + case M_DHT: + { + read_dht_marker(); + break; + } + // No arithmitic support - dumb patents! + case M_DAC: + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + case M_DQT: + { + read_dqt_marker(); + break; + } + case M_DRI: + { + read_dri_marker(); + break; + } + //case M_APP0: /* no need to read the JFIF marker */ + case M_JPG: + case M_RST0: /* no parameters */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + { + stop_decoding(JPGD_UNEXPECTED_MARKER); + break; + } + default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ + { + skip_variable_marker(); + break; + } + } + } + } + + // Finds the start of image (SOI) marker. + void jpeg_decoder::locate_soi_marker() + { + uint lastchar, thischar; + uint bytesleft; + + lastchar = get_bits(8); + + thischar = get_bits(8); + + /* ok if it's a normal JPEG file without a special header */ + + if ((lastchar == 0xFF) && (thischar == M_SOI)) + return; + + bytesleft = 4096; + + for (; ; ) + { + if (--bytesleft == 0) + stop_decoding(JPGD_NOT_JPEG); + + lastchar = thischar; + + thischar = get_bits(8); + + if (lastchar == 0xFF) + { + if (thischar == M_SOI) + break; + else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end + stop_decoding(JPGD_NOT_JPEG); + } + } + + // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. + thischar = (m_bit_buf >> 24) & 0xFF; + + if (thischar != 0xFF) + stop_decoding(JPGD_NOT_JPEG); + } + + // Find a start of frame (SOF) marker. + void jpeg_decoder::locate_sof_marker() + { + locate_soi_marker(); + + int c = process_markers(); + + switch (c) + { + case M_SOF2: + { + m_progressive_flag = JPGD_TRUE; + read_sof_marker(); + break; + } + case M_SOF0: /* baseline DCT */ + case M_SOF1: /* extended sequential DCT */ + { + read_sof_marker(); + break; + } + case M_SOF9: /* Arithmitic coding */ + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + default: + { + stop_decoding(JPGD_UNSUPPORTED_MARKER); + break; + } + } + } - while (num_left) - { - get_bits(8); - num_left--; - } -} + // Find a start of scan (SOS) marker. + int jpeg_decoder::locate_sos_marker() + { + int c; -// Read a define restart interval (DRI) marker. -void jpeg_decoder::read_dri_marker() -{ - if (get_bits(16) != 4) - stop_decoding(JPGD_BAD_DRI_LENGTH); + c = process_markers(); - m_restart_interval = get_bits(16); -} + if (c == M_EOI) + return JPGD_FALSE; + else if (c != M_SOS) + stop_decoding(JPGD_UNEXPECTED_MARKER); -// Read a start of scan (SOS) marker. -void jpeg_decoder::read_sos_marker() -{ - uint num_left; - int i, ci, n, c, cc; + read_sos_marker(); - num_left = get_bits(16); + return JPGD_TRUE; + } - n = get_bits(8); - - m_comps_in_scan = n; - - num_left -= 3; - - if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) ) - stop_decoding(JPGD_BAD_SOS_LENGTH); - - for (i = 0; i < n; i++) - { - cc = get_bits(8); - c = get_bits(8); - num_left -= 2; - - for (ci = 0; ci < m_comps_in_frame; ci++) - if (cc == m_comp_ident[ci]) - break; - - if (ci >= m_comps_in_frame) - stop_decoding(JPGD_BAD_SOS_COMP_ID); - - m_comp_list[i] = ci; - m_comp_dc_tab[ci] = (c >> 4) & 15; - m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); - } - - m_spectral_start = get_bits(8); - m_spectral_end = get_bits(8); - m_successive_high = get_bits(4); - m_successive_low = get_bits(4); - - if (!m_progressive_flag) - { - m_spectral_start = 0; - m_spectral_end = 63; - } - - num_left -= 3; - - while (num_left) /* read past whatever is num_left */ - { - get_bits(8); - num_left--; - } -} - -// Finds the next marker. -int jpeg_decoder::next_marker() -{ - uint c, bytes; - - bytes = 0; - - do - { - do - { - bytes++; - c = get_bits(8); - } while (c != 0xFF); - - do - { - c = get_bits(8); - } while (c == 0xFF); - - } while (c == 0); - - // If bytes > 0 here, there where extra bytes before the marker (not good). - - return c; -} - -// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is -// encountered. -int jpeg_decoder::process_markers() -{ - int c; - - for ( ; ; ) - { - c = next_marker(); - - switch (c) - { - case M_SOF0: - case M_SOF1: - case M_SOF2: - case M_SOF3: - case M_SOF5: - case M_SOF6: - case M_SOF7: -// case M_JPG: - case M_SOF9: - case M_SOF10: - case M_SOF11: - case M_SOF13: - case M_SOF14: - case M_SOF15: - case M_SOI: - case M_EOI: - case M_SOS: - { - return c; - } - case M_DHT: - { - read_dht_marker(); - break; - } - // No arithmitic support - dumb patents! - case M_DAC: - { - stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); - break; - } - case M_DQT: - { - read_dqt_marker(); - break; - } - case M_DRI: - { - read_dri_marker(); - break; - } - //case M_APP0: /* no need to read the JFIF marker */ - - case M_JPG: - case M_RST0: /* no parameters */ - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - case M_TEM: - { - stop_decoding(JPGD_UNEXPECTED_MARKER); - break; - } - default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ - { - skip_variable_marker(); - break; - } - } - } -} - -// Finds the start of image (SOI) marker. -// This code is rather defensive: it only checks the first 512 bytes to avoid -// false positives. -void jpeg_decoder::locate_soi_marker() -{ - uint lastchar, thischar; - uint bytesleft; - - lastchar = get_bits(8); - - thischar = get_bits(8); - - /* ok if it's a normal JPEG file without a special header */ - - if ((lastchar == 0xFF) && (thischar == M_SOI)) - return; - - bytesleft = 4096; //512; - - for ( ; ; ) - { - if (--bytesleft == 0) - stop_decoding(JPGD_NOT_JPEG); - - lastchar = thischar; - - thischar = get_bits(8); - - if (lastchar == 0xFF) - { - if (thischar == M_SOI) - break; - else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end - stop_decoding(JPGD_NOT_JPEG); - } - } - - // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. - thischar = (m_bit_buf >> 24) & 0xFF; - - if (thischar != 0xFF) - stop_decoding(JPGD_NOT_JPEG); -} - -// Find a start of frame (SOF) marker. -void jpeg_decoder::locate_sof_marker() -{ - locate_soi_marker(); - - int c = process_markers(); - - switch (c) - { - case M_SOF2: - m_progressive_flag = JPGD_TRUE; - case M_SOF0: /* baseline DCT */ - case M_SOF1: /* extended sequential DCT */ - { - read_sof_marker(); - break; - } - case M_SOF9: /* Arithmitic coding */ - { - stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); - break; - } - default: - { - stop_decoding(JPGD_UNSUPPORTED_MARKER); - break; - } - } -} - -// Find a start of scan (SOS) marker. -int jpeg_decoder::locate_sos_marker() -{ - int c; - - c = process_markers(); - - if (c == M_EOI) - return JPGD_FALSE; - else if (c != M_SOS) - stop_decoding(JPGD_UNEXPECTED_MARKER); - - read_sos_marker(); - - return JPGD_TRUE; -} - -// Reset everything to default/uninitialized state. -void jpeg_decoder::init(jpeg_decoder_stream *pStream) -{ - m_pMem_blocks = NULL; - m_error_code = JPGD_SUCCESS; - m_ready_flag = false; - m_image_x_size = m_image_y_size = 0; - m_pStream = pStream; - m_progressive_flag = JPGD_FALSE; - - memset(m_huff_ac, 0, sizeof(m_huff_ac)); - memset(m_huff_num, 0, sizeof(m_huff_num)); - memset(m_huff_val, 0, sizeof(m_huff_val)); - memset(m_quant, 0, sizeof(m_quant)); - - m_scan_type = 0; - m_comps_in_frame = 0; - - memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); - memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); - memset(m_comp_quant, 0, sizeof(m_comp_quant)); - memset(m_comp_ident, 0, sizeof(m_comp_ident)); - memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); - memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); - - m_comps_in_scan = 0; - memset(m_comp_list, 0, sizeof(m_comp_list)); - memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); - memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); - - m_spectral_start = 0; - m_spectral_end = 0; - m_successive_low = 0; - m_successive_high = 0; - m_max_mcu_x_size = 0; - m_max_mcu_y_size = 0; - m_blocks_per_mcu = 0; - m_max_blocks_per_row = 0; - m_mcus_per_row = 0; - m_mcus_per_col = 0; - m_expanded_blocks_per_component = 0; - m_expanded_blocks_per_mcu = 0; - m_expanded_blocks_per_row = 0; - m_freq_domain_chroma_upsample = false; - - memset(m_mcu_org, 0, sizeof(m_mcu_org)); - - m_total_lines_left = 0; - m_mcu_lines_left = 0; - m_real_dest_bytes_per_scan_line = 0; - m_dest_bytes_per_scan_line = 0; - m_dest_bytes_per_pixel = 0; - - memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); - - memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); - memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - m_eob_run = 0; - - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - m_pIn_buf_ofs = m_in_buf; - m_in_buf_left = 0; - m_eof_flag = false; - m_tem_flag = 0; - - memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); - memset(m_in_buf, 0, sizeof(m_in_buf)); - memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); - - m_restart_interval = 0; - m_restarts_left = 0; - m_next_restart_num = 0; - - m_max_mcus_per_row = 0; - m_max_blocks_per_mcu = 0; - m_max_mcus_per_col = 0; - - memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); - m_pMCU_coefficients = NULL; - m_pSample_buf = NULL; - - m_total_bytes_read = 0; - - m_pScan_line_0 = NULL; - m_pScan_line_1 = NULL; - - // Ready the input buffer. - prep_in_buffer(); - - // Prime the bit buffer. - m_bits_left = 16; - m_bit_buf = 0; - - get_bits(16); - get_bits(16); - - for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) - m_mcu_block_max_zag[i] = 64; -} + // Reset everything to default/uninitialized state. + void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags) + { + m_flags = flags; + m_pMem_blocks = nullptr; + m_error_code = JPGD_SUCCESS; + m_ready_flag = false; + m_image_x_size = m_image_y_size = 0; + m_pStream = pStream; + m_progressive_flag = JPGD_FALSE; + + memset(m_huff_ac, 0, sizeof(m_huff_ac)); + memset(m_huff_num, 0, sizeof(m_huff_num)); + memset(m_huff_val, 0, sizeof(m_huff_val)); + memset(m_quant, 0, sizeof(m_quant)); + + m_scan_type = 0; + m_comps_in_frame = 0; + + memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); + memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); + memset(m_comp_quant, 0, sizeof(m_comp_quant)); + memset(m_comp_ident, 0, sizeof(m_comp_ident)); + memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); + memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); + + m_comps_in_scan = 0; + memset(m_comp_list, 0, sizeof(m_comp_list)); + memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); + memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); + + m_spectral_start = 0; + m_spectral_end = 0; + m_successive_low = 0; + m_successive_high = 0; + m_max_mcu_x_size = 0; + m_max_mcu_y_size = 0; + m_blocks_per_mcu = 0; + m_max_blocks_per_row = 0; + m_mcus_per_row = 0; + m_mcus_per_col = 0; + + memset(m_mcu_org, 0, sizeof(m_mcu_org)); + + m_total_lines_left = 0; + m_mcu_lines_left = 0; + m_num_buffered_scanlines = 0; + m_real_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_pixel = 0; + + memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); + + memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); + memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_eob_run = 0; + + m_pIn_buf_ofs = m_in_buf; + m_in_buf_left = 0; + m_eof_flag = false; + m_tem_flag = 0; + + memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); + memset(m_in_buf, 0, sizeof(m_in_buf)); + memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); + + m_restart_interval = 0; + m_restarts_left = 0; + m_next_restart_num = 0; + + m_max_mcus_per_row = 0; + m_max_blocks_per_mcu = 0; + m_max_mcus_per_col = 0; + + memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); + m_pMCU_coefficients = nullptr; + m_pSample_buf = nullptr; + m_pSample_buf_prev = nullptr; + m_sample_buf_prev_valid = false; + + m_total_bytes_read = 0; + + m_pScan_line_0 = nullptr; + m_pScan_line_1 = nullptr; + + // Ready the input buffer. + prep_in_buffer(); + + // Prime the bit buffer. + m_bits_left = 16; + m_bit_buf = 0; + + get_bits(16); + get_bits(16); + + for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) + m_mcu_block_max_zag[i] = 64; + + m_has_sse2 = false; + +#if JPGD_USE_SSE2 +#ifdef _MSC_VER + int cpu_info[4]; + __cpuid(cpu_info, 1); + const int cpu_info3 = cpu_info[3]; + m_has_sse2 = ((cpu_info3 >> 26U) & 1U) != 0U; +#else + m_has_sse2 = true; +#endif +#endif + } #define SCALEBITS 16 #define ONE_HALF ((int) 1 << (SCALEBITS-1)) #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f)) -// Create a few tables that allow us to quickly convert YCbCr to RGB. -void jpeg_decoder::create_look_ups() -{ - for (int i = 0; i <= 255; i++) - { - int k = i - 128; - m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; - m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; - m_crg[i] = (-FIX(0.71414f)) * k; - m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; - } -} - -// This method throws back into the stream any bytes that where read -// into the bit buffer during initial marker scanning. -void jpeg_decoder::fix_in_buffer() -{ - // In case any 0xFF's where pulled into the buffer during marker scanning. - JPGD_ASSERT((m_bits_left & 7) == 0); - - if (m_bits_left == 16) - stuff_char( (uint8)(m_bit_buf & 0xFF)); - - if (m_bits_left >= 8) - stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF)); - - stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); - stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); - - m_bits_left = 16; - get_bits_no_markers(16); - get_bits_no_markers(16); -} - -void jpeg_decoder::transform_mcu(int mcu_row) -{ - jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; - if (m_freq_domain_chroma_upsample) { - JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row); - } - else { - JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row); - } - uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; - - for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); - pSrc_ptr += 64; - pDst_ptr += 64; - } -} - -static const uint8 s_max_rc[64] = -{ - 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, - 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136 -}; - -void jpeg_decoder::transform_mcu_expand(int mcu_row) -{ - jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; - uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64; - - // Y IDCT - int mcu_block; - for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++) - { - idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); - pSrc_ptr += 64; - pDst_ptr += 64; - } - - // Chroma IDCT, with upsampling - jpgd_block_t temp_block[64]; - - for (int i = 0; i < 2; i++) - { - DCT_Upsample::Matrix44 P, Q, R, S; - - JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1); - JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64); - - int max_zag = m_mcu_block_max_zag[mcu_block++] - 1; - if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis - switch (s_max_rc[max_zag]) - { - case 1*16+1: - DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr); - break; - case 1*16+2: - DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr); - break; - case 2*16+2: - DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr); - break; - case 3*16+2: - DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr); - break; - case 3*16+3: - DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr); - break; - case 3*16+4: - DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr); - break; - case 4*16+4: - DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr); - break; - case 5*16+4: - DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr); - break; - case 5*16+5: - DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr); - break; - case 5*16+6: - DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr); - break; - case 6*16+6: - DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr); - break; - case 7*16+6: - DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr); - break; - case 7*16+7: - DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr); - break; - case 7*16+8: - DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr); - break; - case 8*16+8: - DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr); - break; - default: - JPGD_ASSERT(false); - } - - DCT_Upsample::Matrix44 a(P + Q); P -= Q; - DCT_Upsample::Matrix44& b = P; - DCT_Upsample::Matrix44 c(R + S); R -= S; - DCT_Upsample::Matrix44& d = R; - - DCT_Upsample::Matrix44::add_and_store(temp_block, a, c); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::add_and_store(temp_block, b, d); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - pSrc_ptr += 64; - } -} - -// Loads and dequantizes the next row of (already decoded) coefficients. -// Progressive images only. -void jpeg_decoder::load_next_row() -{ - int i; - jpgd_block_t *p; - jpgd_quant_t *q; - int mcu_row, mcu_block, row_block = 0; - int component_num, component_id; - int block_x_mcu[JPGD_MAX_COMPONENTS]; - - memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); - - for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; - - for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - component_id = m_mcu_org[mcu_block]; - JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES); - q = m_quant[m_comp_quant[component_id]]; - - p = m_pMCU_coefficients + 64 * mcu_block; - - jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - p[0] = pDC[0]; - memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t)); - - for (i = 63; i > 0; i--) - if (p[g_ZAG[i]]) - break; - - m_mcu_block_max_zag[mcu_block] = i + 1; - - for ( ; i >= 0; i--) - if (p[g_ZAG[i]]) - p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]); - - row_block++; - - if (m_comps_in_scan == 1) - block_x_mcu[component_id]++; - else - { - if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) - { - block_x_mcu_ofs = 0; - - if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) - { - block_y_mcu_ofs = 0; - - block_x_mcu[component_id] += m_comp_h_samp[component_id]; - } - } - } - } - - if (m_freq_domain_chroma_upsample) - transform_mcu_expand(mcu_row); - else - transform_mcu(mcu_row); - } - - if (m_comps_in_scan == 1) - m_block_y_mcu[m_comp_list[0]]++; - else - { - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - component_id = m_comp_list[component_num]; - - m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; - } - } -} - -// Restart interval processing. -void jpeg_decoder::process_restart() -{ - int i; - int c = 0; - - // Align to a byte boundry - // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! - //get_bits_no_markers(m_bits_left & 7); - - // Let's scan a little bit to find the marker, but not _too_ far. - // 1536 is a "fudge factor" that determines how much to scan. - for (i = 1536; i > 0; i--) - if (get_char() == 0xFF) - break; - - if (i == 0) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - for ( ; i > 0; i--) - if ((c = get_char()) != 0xFF) - break; - - if (i == 0) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - // Is it the expected marker? If not, something bad happened. - if (c != (m_next_restart_num + M_RST0)) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - // Reset each component's DC prediction values. - memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); - - m_eob_run = 0; - - m_restarts_left = m_restart_interval; - - m_next_restart_num = (m_next_restart_num + 1) & 7; - - // Get the bit buffer going again... - - m_bits_left = 16; - get_bits_no_markers(16); - get_bits_no_markers(16); -} - -static inline int dequantize_ac(int c, int q) { c *= q; return c; } - -// Decodes and dequantizes the next row of coefficients. -void jpeg_decoder::decode_next_row() -{ - int row_block = 0; - - for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - if ((m_restart_interval) && (m_restarts_left == 0)) - process_restart(); - - jpgd_block_t* p = m_pMCU_coefficients; - for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) - { - int component_id = m_mcu_org[mcu_block]; - JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES); - jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; - - int r, s; - s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); - s = JPGD_HUFF_EXTEND(r, s); - - m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); - - p[0] = static_cast<jpgd_block_t>(s * q[0]); - - int prev_num_set = m_mcu_block_max_zag[mcu_block]; - - huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; - - int k; - for (k = 1; k < 64; k++) - { - int extra_bits; - s = huff_decode(pH, extra_bits); - - r = s >> 4; - s &= 15; - - if (s) - { - if (r) - { - if ((k + r) > 63) - stop_decoding(JPGD_DECODE_ERROR); - - if (k < prev_num_set) - { - int n = JPGD_MIN(r, prev_num_set - k); - int kt = k; - while (n--) - p[g_ZAG[kt++]] = 0; - } - - k += r; - } - - s = JPGD_HUFF_EXTEND(extra_bits, s); - - JPGD_ASSERT(k < 64); - - p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k]; - } - else - { - if (r == 15) - { - if ((k + 16) > 64) - stop_decoding(JPGD_DECODE_ERROR); - - if (k < prev_num_set) - { - int n = JPGD_MIN(16, prev_num_set - k); - int kt = k; - while (n--) - { - JPGD_ASSERT(kt <= 63); - p[g_ZAG[kt++]] = 0; - } - } - - k += 16 - 1; // - 1 because the loop counter is k - JPGD_ASSERT(p[g_ZAG[k]] == 0); - } - else - break; - } - } - - if (k < prev_num_set) - { - int kt = k; - while (kt < prev_num_set) - p[g_ZAG[kt++]] = 0; - } - - m_mcu_block_max_zag[mcu_block] = k; - - row_block++; - } - - if (m_freq_domain_chroma_upsample) - transform_mcu_expand(mcu_row); - else - transform_mcu(mcu_row); - - m_restarts_left--; - } -} - -// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB -void jpeg_decoder::H1V1Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d = m_pScan_line_0; - uint8 *s = m_pSample_buf + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int j = 0; j < 8; j++) - { - int y = s[j]; - int cb = s[64+j]; - int cr = s[128+j]; - - d[0] = clamp(y + m_crr[cr]); - d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); - d[2] = clamp(y + m_cbb[cb]); - d[3] = 255; - - d += 4; - } - - s += 64*3; - } -} - -// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB -void jpeg_decoder::H2V1Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *y = m_pSample_buf + row * 8; - uint8 *c = m_pSample_buf + 2*64 + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int l = 0; l < 2; l++) - { - for (int j = 0; j < 4; j++) - { - int cb = c[0]; - int cr = c[64]; - - int rc = m_crr[cr]; - int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); - int bc = m_cbb[cb]; - - int yy = y[j<<1]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); - d0[3] = 255; - - yy = y[(j<<1)+1]; - d0[4] = clamp(yy+rc); - d0[5] = clamp(yy+gc); - d0[6] = clamp(yy+bc); - d0[7] = 255; - - d0 += 8; - - c++; - } - y += 64; - } - - y += 64*4 - 64*2; - c += 64*4 - 8; - } -} - -// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB -void jpeg_decoder::H1V2Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *d1 = m_pScan_line_1; - uint8 *y; - uint8 *c; - - if (row < 8) - y = m_pSample_buf + row * 8; - else - y = m_pSample_buf + 64*1 + (row & 7) * 8; - - c = m_pSample_buf + 64*2 + (row >> 1) * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int j = 0; j < 8; j++) - { - int cb = c[0+j]; - int cr = c[64+j]; - - int rc = m_crr[cr]; - int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); - int bc = m_cbb[cb]; - - int yy = y[j]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); - d0[3] = 255; - - yy = y[8+j]; - d1[0] = clamp(yy+rc); - d1[1] = clamp(yy+gc); - d1[2] = clamp(yy+bc); - d1[3] = 255; - - d0 += 4; - d1 += 4; - } - - y += 64*4; - c += 64*4; - } -} - -// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB -void jpeg_decoder::H2V2Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *d1 = m_pScan_line_1; - uint8 *y; - uint8 *c; - - if (row < 8) - y = m_pSample_buf + row * 8; - else - y = m_pSample_buf + 64*2 + (row & 7) * 8; - - c = m_pSample_buf + 64*4 + (row >> 1) * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int l = 0; l < 2; l++) - { - for (int j = 0; j < 8; j += 2) - { - int cb = c[0]; - int cr = c[64]; + // Create a few tables that allow us to quickly convert YCbCr to RGB. + void jpeg_decoder::create_look_ups() + { + for (int i = 0; i <= 255; i++) + { + int k = i - 128; + m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; + m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; + m_crg[i] = (-FIX(0.71414f)) * k; + m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; + } + } + + // This method throws back into the stream any bytes that where read + // into the bit buffer during initial marker scanning. + void jpeg_decoder::fix_in_buffer() + { + // In case any 0xFF's where pulled into the buffer during marker scanning. + assert((m_bits_left & 7) == 0); + + if (m_bits_left == 16) + stuff_char((uint8)(m_bit_buf & 0xFF)); + + if (m_bits_left >= 8) + stuff_char((uint8)((m_bit_buf >> 8) & 0xFF)); + + stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); + stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + void jpeg_decoder::transform_mcu(int mcu_row) + { + jpgd_block_coeff_t* pSrc_ptr = m_pMCU_coefficients; + if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row) + stop_decoding(JPGD_DECODE_ERROR); + + uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block], ((m_flags & cFlagDisableSIMD) == 0) && m_has_sse2); + pSrc_ptr += 64; + pDst_ptr += 64; + } + } + + // Loads and dequantizes the next row of (already decoded) coefficients. + // Progressive images only. + void jpeg_decoder::load_next_row() + { + int i; + jpgd_block_coeff_t* p; + jpgd_quant_t* q; + int mcu_row, mcu_block, row_block = 0; + int component_num, component_id; + int block_x_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + q = m_quant[m_comp_quant[component_id]]; + + p = m_pMCU_coefficients + 64 * mcu_block; + + jpgd_block_coeff_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + jpgd_block_coeff_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + p[0] = pDC[0]; + memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_coeff_t)); + + for (i = 63; i > 0; i--) + if (p[g_ZAG[i]]) + break; + + m_mcu_block_max_zag[mcu_block] = i + 1; + + for (; i >= 0; i--) + if (p[g_ZAG[i]]) + p[g_ZAG[i]] = static_cast<jpgd_block_coeff_t>(p[g_ZAG[i]] * q[i]); + + row_block++; + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + transform_mcu(mcu_row); + } + + if (m_comps_in_scan == 1) + m_block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + + // Restart interval processing. + void jpeg_decoder::process_restart() + { + int i; + int c = 0; + + // Align to a byte boundry + // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! + //get_bits_no_markers(m_bits_left & 7); + + // Let's scan a little bit to find the marker, but not _too_ far. + // 1536 is a "fudge factor" that determines how much to scan. + for (i = 1536; i > 0; i--) + if (get_char() == 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + for (; i > 0; i--) + if ((c = get_char()) != 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Is it the expected marker? If not, something bad happened. + if (c != (m_next_restart_num + M_RST0)) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Reset each component's DC prediction values. + memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + m_restarts_left = m_restart_interval; + + m_next_restart_num = (m_next_restart_num + 1) & 7; + + // Get the bit buffer going again... + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + static inline int dequantize_ac(int c, int q) { c *= q; return c; } + + // Decodes and dequantizes the next row of coefficients. + void jpeg_decoder::decode_next_row() + { + int row_block = 0; + + for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + jpgd_block_coeff_t* p = m_pMCU_coefficients; + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) + { + int component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; + + int r, s; + s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); + if (s >= 16) + stop_decoding(JPGD_DECODE_ERROR); + + s = JPGD_HUFF_EXTEND(r, s); + + m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_coeff_t>(s * q[0]); + + int prev_num_set = m_mcu_block_max_zag[mcu_block]; + + huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; + + int k; + for (k = 1; k < 64; k++) + { + int extra_bits; + s = huff_decode(pH, extra_bits); + + r = s >> 4; + s &= 15; + + if (s) + { + if (r) + { + if ((k + r) > 63) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(r, prev_num_set - k); + int kt = k; + while (n--) + p[g_ZAG[kt++]] = 0; + } + + k += r; + } + + s = JPGD_HUFF_EXTEND(extra_bits, s); + + if (k >= 64) + stop_decoding(JPGD_DECODE_ERROR); + + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(dequantize_ac(s, q[k])); //s * q[k]; + } + else + { + if (r == 15) + { + if ((k + 16) > 64) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(16, prev_num_set - k); + int kt = k; + while (n--) + { + if (kt > 63) + stop_decoding(JPGD_DECODE_ERROR); + p[g_ZAG[kt++]] = 0; + } + } + + k += 16 - 1; // - 1 because the loop counter is k + + if (p[g_ZAG[k & 63]] != 0) + stop_decoding(JPGD_DECODE_ERROR); + } + else + break; + } + } + + if (k < prev_num_set) + { + int kt = k; + while (kt < prev_num_set) + p[g_ZAG[kt++]] = 0; + } + + m_mcu_block_max_zag[mcu_block] = k; + + row_block++; + } + + transform_mcu(mcu_row); + + m_restarts_left--; + } + } + + // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB + void jpeg_decoder::H1V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int y = s[j]; + int cb = s[64 + j]; + int cr = s[128 + j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + + s += 64 * 3; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* y = m_pSample_buf + row * 8; + uint8* c = m_pSample_buf + 2 * 64 + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 4; j++) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j << 1]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[(j << 1) + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + d0 += 8; + + c++; + } + y += 64; + } + + y += 64 * 4 - 64 * 2; + c += 64 * 4 - 8; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + const int row_x8 = row * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128; + int cb0 = m_pSample_buf[check_sample_buf_ofs(a)]; + int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128; + int cb1 = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int w0 = (x & 1) ? 3 : 1; + int w1 = (x & 1) ? 1 : 3; + + int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2; + int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y + rc); + d0[1] = clamp(y + gc); + d0[2] = clamp(y + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 1 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 2 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int cb = c[0 + j]; + int cr = c[64 + j]; int rc = m_crr[cr]; int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); int bc = m_cbb[cb]; int yy = y[j]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); d0[3] = 255; - yy = y[j+1]; - d0[4] = clamp(yy+rc); - d0[5] = clamp(yy+gc); - d0[6] = clamp(yy+bc); - d0[7] = 255; - - yy = y[j+8]; - d1[0] = clamp(yy+rc); - d1[1] = clamp(yy+gc); - d1[2] = clamp(yy+bc); + yy = y[8 + j]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); d1[3] = 255; - yy = y[j+8+1]; - d1[4] = clamp(yy+rc); - d1[5] = clamp(yy+gc); - d1[6] = clamp(yy+bc); - d1[7] = 255; + d0 += 4; + d1 += 4; + } + + y += 64 * 4; + c += 64 * 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + const int w0 = (row & 1) ? 3 : 1; + const int w1 = (row & 1) ? 1 : 3; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; - d0 += 8; - d1 += 8; + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 128; + const int y1_base = (c_y1 & 7) * 8 + 128; + + for (int x = 0; x < m_image_x_size; x++) + { + const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7); + + int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)]; + + int a = base_ofs + y0_base; + int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)]; + int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)]; + + int b = base_ofs + y1_base; + int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2; + int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB + void jpeg_decoder::H2V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; - c++; + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 2 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 4 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 8; j += 2) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[j + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + yy = y[j + 8]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); + d1[3] = 255; + + yy = y[j + 8 + 1]; + d1[4] = clamp(yy + rc); + d1[5] = clamp(yy + gc); + d1[6] = clamp(yy + bc); + d1[7] = 255; + + d0 += 8; + d1 += 8; + + c++; + } + y += 64; } - y += 64; - } - - y += 64*6 - 64*2; - c += 64*6 - 8; - } -} - -// Y (1 block per MCU) to 8-bit grayscale -void jpeg_decoder::gray_convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d = m_pScan_line_0; - uint8 *s = m_pSample_buf + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - *(uint *)d = *(uint *)s; - *(uint *)(&d[4]) = *(uint *)(&s[4]); - - s += 64; - d += 8; - } -} - -void jpeg_decoder::expanded_convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - - uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8; - - uint8* d = m_pScan_line_0; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int k = 0; k < m_max_mcu_x_size; k += 8) - { - const int Y_ofs = k * 8; - const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component; - const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2; - for (int j = 0; j < 8; j++) - { - int y = Py[Y_ofs + j]; - int cb = Py[Cb_ofs + j]; - int cr = Py[Cr_ofs + j]; - - d[0] = clamp(y + m_crr[cr]); - d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); - d[2] = clamp(y + m_cbb[cb]); - d[3] = 255; - - d += 4; - } - } - - Py += 64 * m_expanded_blocks_per_mcu; - } -} - -// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. -void jpeg_decoder::find_eoi() -{ - if (!m_progressive_flag) - { - // Attempt to read the EOI marker. - //get_bits_no_markers(m_bits_left & 7); - - // Prime the bit buffer - m_bits_left = 16; - get_bits(16); - get_bits(16); - - // The next marker _should_ be EOI - process_markers(); - } - - m_total_bytes_read -= m_in_buf_left; -} - -int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) -{ - if ((m_error_code) || (!m_ready_flag)) - return JPGD_FAILED; - - if (m_total_lines_left == 0) - return JPGD_DONE; - - if (m_mcu_lines_left == 0) - { - if (setjmp(m_jmp_state)) - return JPGD_FAILED; - - if (m_progressive_flag) - load_next_row(); - else - decode_next_row(); - - // Find the EOI marker if that was the last row. - if (m_total_lines_left <= m_max_mcu_y_size) - find_eoi(); - - m_mcu_lines_left = m_max_mcu_y_size; - } - - if (m_freq_domain_chroma_upsample) - { - expanded_convert(); - *pScan_line = m_pScan_line_0; - } - else - { - switch (m_scan_type) - { - case JPGD_YH2V2: - { - if ((m_mcu_lines_left & 1) == 0) - { - H2V2Convert(); - *pScan_line = m_pScan_line_0; - } - else - *pScan_line = m_pScan_line_1; - - break; - } - case JPGD_YH2V1: - { - H2V1Convert(); - *pScan_line = m_pScan_line_0; - break; - } - case JPGD_YH1V2: - { - if ((m_mcu_lines_left & 1) == 0) - { - H1V2Convert(); - *pScan_line = m_pScan_line_0; - } - else - *pScan_line = m_pScan_line_1; - - break; - } - case JPGD_YH1V1: - { - H1V1Convert(); - *pScan_line = m_pScan_line_0; - break; - } - case JPGD_GRAYSCALE: - { - gray_convert(); - *pScan_line = m_pScan_line_0; - - break; - } - } - } - - *pScan_line_len = m_real_dest_bytes_per_scan_line; - - m_mcu_lines_left--; - m_total_lines_left--; - - return JPGD_SUCCESS; -} - -// Creates the tables needed for efficient Huffman decoding. -void jpeg_decoder::make_huff_table(int index, huff_tables *pH) -{ - int p, i, l, si; - uint8 huffsize[257]; - uint huffcode[257]; - uint code; - uint subtree; - int code_size; - int lastp; - int nextfreeentry; - int currententry; - - pH->ac_table = m_huff_ac[index] != 0; - - p = 0; - - for (l = 1; l <= 16; l++) - { - for (i = 1; i <= m_huff_num[index][l]; i++) - { - JPGD_ASSERT(p < 257); - huffsize[p++] = static_cast<uint8>(l); - } - } - - huffsize[p] = 0; - - lastp = p; - - code = 0; - si = huffsize[0]; - p = 0; - - while (huffsize[p]) - { - while (huffsize[p] == si) - { - JPGD_ASSERT(p < 257); - huffcode[p++] = code; - code++; - } - - code <<= 1; - si++; - } - - memset(pH->look_up, 0, sizeof(pH->look_up)); - memset(pH->look_up2, 0, sizeof(pH->look_up2)); - memset(pH->tree, 0, sizeof(pH->tree)); - memset(pH->code_size, 0, sizeof(pH->code_size)); - - nextfreeentry = -1; - - p = 0; - - while (p < lastp) - { - i = m_huff_val[index][p]; - code = huffcode[p]; - code_size = huffsize[p]; - - pH->code_size[i] = static_cast<uint8>(code_size); - - if (code_size <= 8) - { - code <<= (8 - code_size); - - for (l = 1 << (8 - code_size); l > 0; l--) - { - JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - - pH->look_up[code] = i; - - bool has_extrabits = false; - int extra_bits = 0; - int num_extra_bits = i & 15; - - int bits_to_fetch = code_size; - if (num_extra_bits) - { - int total_codesize = code_size + num_extra_bits; - if (total_codesize <= 8) - { - has_extrabits = true; - extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); - JPGD_ASSERT(extra_bits <= 0x7FFF); - bits_to_fetch += num_extra_bits; - } - } - - if (!has_extrabits) - pH->look_up2[code] = i | (bits_to_fetch << 8); - else - pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); - - code++; - } - } - else - { - subtree = (code >> (code_size - 8)) & 0xFF; - - currententry = pH->look_up[subtree]; - - if (currententry == 0) - { - pH->look_up[subtree] = currententry = nextfreeentry; - pH->look_up2[subtree] = currententry = nextfreeentry; - - nextfreeentry -= 2; - } - - code <<= (16 - (code_size - 8)); - - for (l = code_size; l > 9; l--) - { - if ((code & 0x8000) == 0) - currententry--; - - unsigned int idx = -currententry - 1; - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - if (pH->tree[idx] == 0) - { - pH->tree[idx] = nextfreeentry; - - currententry = nextfreeentry; - - nextfreeentry -= 2; - } - else { - currententry = pH->tree[idx]; - } - - code <<= 1; - } - - if ((code & 0x8000) == 0) - currententry--; - - pH->tree[-currententry - 1] = i; - } - - p++; - } -} - -// Verifies the quantization tables needed for this scan are available. -void jpeg_decoder::check_quant_tables() -{ - for (int i = 0; i < m_comps_in_scan; i++) - if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL) - stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); -} - -// Verifies that all the Huffman tables needed for this scan are available. -void jpeg_decoder::check_huff_tables() -{ - for (int i = 0; i < m_comps_in_scan; i++) - { - if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL)) - stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); - - if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL)) - stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); - } - - for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) - if (m_huff_num[i]) - { - if (!m_pHuff_tabs[i]) - m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables)); - - make_huff_table(i, m_pHuff_tabs[i]); - } -} - -// Determines the component order inside each MCU. -// Also calcs how many MCU's are on each row, etc. -void jpeg_decoder::calc_mcu_block_order() -{ - int component_num, component_id; - int max_h_samp = 0, max_v_samp = 0; - - for (component_id = 0; component_id < m_comps_in_frame; component_id++) - { - if (m_comp_h_samp[component_id] > max_h_samp) - max_h_samp = m_comp_h_samp[component_id]; - - if (m_comp_v_samp[component_id] > max_v_samp) - max_v_samp = m_comp_v_samp[component_id]; - } - - for (component_id = 0; component_id < m_comps_in_frame; component_id++) - { - m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; - m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; - } - - if (m_comps_in_scan == 1) - { - m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; - m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; - } - else - { - m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; - m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; - } - - if (m_comps_in_scan == 1) - { - m_mcu_org[0] = m_comp_list[0]; - - m_blocks_per_mcu = 1; - } - else - { - m_blocks_per_mcu = 0; - - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - int num_blocks; - - component_id = m_comp_list[component_num]; - - num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; - - while (num_blocks--) - m_mcu_org[m_blocks_per_mcu++] = component_id; - } - } -} - -// Starts a new scan. -int jpeg_decoder::init_scan() -{ - if (!locate_sos_marker()) - return JPGD_FALSE; - - calc_mcu_block_order(); - - check_huff_tables(); - - check_quant_tables(); - - memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); - - m_eob_run = 0; - - if (m_restart_interval) - { - m_restarts_left = m_restart_interval; - m_next_restart_num = 0; - } - - fix_in_buffer(); - - return JPGD_TRUE; -} - -// Starts a frame. Determines if the number of components or sampling factors -// are supported. -void jpeg_decoder::init_frame() -{ - int i; - - if (m_comps_in_frame == 1) - { - if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - - m_scan_type = JPGD_GRAYSCALE; - m_max_blocks_per_mcu = 1; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 8; - } - else if (m_comps_in_frame == 3) - { - if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || - ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) ) - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - - if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) - { - m_scan_type = JPGD_YH1V1; - - m_max_blocks_per_mcu = 3; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 8; - } - else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) - { - m_scan_type = JPGD_YH2V1; - m_max_blocks_per_mcu = 4; - m_max_mcu_x_size = 16; - m_max_mcu_y_size = 8; - } - else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) - { - m_scan_type = JPGD_YH1V2; - m_max_blocks_per_mcu = 4; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 16; - } - else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) - { - m_scan_type = JPGD_YH2V2; - m_max_blocks_per_mcu = 6; - m_max_mcu_x_size = 16; - m_max_mcu_y_size = 16; - } - else - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - } - else - stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); - - m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; - m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; - - // These values are for the *destination* pixels: after conversion. - if (m_scan_type == JPGD_GRAYSCALE) - m_dest_bytes_per_pixel = 1; - else - m_dest_bytes_per_pixel = 4; - - m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; - - m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); - - // Initialize two scan line buffers. - m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); - if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) - m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); - - m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; - - // Should never happen - if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) - stop_decoding(JPGD_ASSERTION_ERROR); - - // Allocate the coefficient buffer, enough for one MCU - m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t)); - - for (i = 0; i < m_max_blocks_per_mcu; i++) - m_mcu_block_max_zag[i] = 64; - - m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0]; - m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame; - m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu; - // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen). - m_freq_domain_chroma_upsample = false; -#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING - m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3); -#endif - if (m_freq_domain_chroma_upsample) - m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64); - else - m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64); - - m_total_lines_left = m_image_y_size; - - m_mcu_lines_left = 0; - - create_look_ups(); -} - -// The coeff_buf series of methods originally stored the coefficients -// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache -// was used to make this process more efficient. Now, we can store the entire -// thing in RAM. -jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) -{ - coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); - - cb->block_num_x = block_num_x; - cb->block_num_y = block_num_y; - cb->block_len_x = block_len_x; - cb->block_len_y = block_len_y; - cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t); - cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true); - return cb; -} - -inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y) -{ - JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y)); - return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); -} - -// The following methods decode the various types of m_blocks encountered -// in progressively encoded images. -void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int s, r; - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); - - if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) - { - r = pD->get_bits_no_markers(s); - s = JPGD_HUFF_EXTEND(r, s); - } - - pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); - - p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low); -} - -void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - if (pD->get_bits_no_markers(1)) - { - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); - - p[0] |= (1 << pD->m_successive_low); - } -} - -void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int k, s, r; - - if (pD->m_eob_run) - { - pD->m_eob_run--; - return; - } - - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); - - for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) - { - unsigned int idx = pD->m_comp_ac_tab[component_id]; - JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES); - s = pD->huff_decode(pD->m_pHuff_tabs[idx]); - - r = s >> 4; - s &= 15; - - if (s) - { - if ((k += r) > 63) - pD->stop_decoding(JPGD_DECODE_ERROR); - - r = pD->get_bits_no_markers(s); - s = JPGD_HUFF_EXTEND(r, s); - - p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low); - } - else - { - if (r == 15) - { - if ((k += 15) > 63) - pD->stop_decoding(JPGD_DECODE_ERROR); - } - else - { - pD->m_eob_run = 1 << r; - - if (r) - pD->m_eob_run += pD->get_bits_no_markers(r); - - pD->m_eob_run--; - - break; - } - } - } -} - -void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int s, k, r; - int p1 = 1 << pD->m_successive_low; - int m1 = (-1) << pD->m_successive_low; - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); - JPGD_ASSERT(pD->m_spectral_end <= 63); - - k = pD->m_spectral_start; - - if (pD->m_eob_run == 0) - { - for ( ; k <= pD->m_spectral_end; k++) - { - unsigned int idx = pD->m_comp_ac_tab[component_id]; - JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES); - s = pD->huff_decode(pD->m_pHuff_tabs[idx]); - - r = s >> 4; - s &= 15; - - if (s) - { - if (s != 1) - pD->stop_decoding(JPGD_DECODE_ERROR); - - if (pD->get_bits_no_markers(1)) - s = p1; - else - s = m1; - } - else - { - if (r != 15) - { - pD->m_eob_run = 1 << r; - - if (r) - pD->m_eob_run += pD->get_bits_no_markers(r); - - break; - } - } - - do - { - jpgd_block_t *this_coef = p + g_ZAG[k & 63]; - - if (*this_coef != 0) - { - if (pD->get_bits_no_markers(1)) - { - if ((*this_coef & p1) == 0) - { - if (*this_coef >= 0) - *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); - else - *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); - } - } - } - else - { - if (--r < 0) - break; - } - - k++; - - } while (k <= pD->m_spectral_end); - - if ((s) && (k < 64)) - { - p[g_ZAG[k]] = static_cast<jpgd_block_t>(s); - } - } - } - - if (pD->m_eob_run > 0) - { - for ( ; k <= pD->m_spectral_end; k++) - { - jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis - - if (*this_coef != 0) - { - if (pD->get_bits_no_markers(1)) - { - if ((*this_coef & p1) == 0) - { - if (*this_coef >= 0) - *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); - else - *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); - } - } - } - } - - pD->m_eob_run--; - } -} - -// Decode a scan in a progressively encoded image. -void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) -{ - int mcu_row, mcu_col, mcu_block; - int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS]; - - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) - { - int component_num, component_id; - - memset(block_x_mcu, 0, sizeof(block_x_mcu)); - - for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; - - if ((m_restart_interval) && (m_restarts_left == 0)) - process_restart(); - - for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - component_id = m_mcu_org[mcu_block]; - - decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - - if (m_comps_in_scan == 1) - block_x_mcu[component_id]++; - else - { - if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) - { - block_x_mcu_ofs = 0; - - if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) - { - block_y_mcu_ofs = 0; - block_x_mcu[component_id] += m_comp_h_samp[component_id]; - } - } - } - } - - m_restarts_left--; - } - - if (m_comps_in_scan == 1) - m_block_y_mcu[m_comp_list[0]]++; - else - { - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - component_id = m_comp_list[component_num]; - m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; - } - } - } -} - -// Decode a progressively encoded image. -void jpeg_decoder::init_progressive() -{ - int i; - - if (m_comps_in_frame == 4) - stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); - - // Allocate the coefficient buffers. - for (i = 0; i < m_comps_in_frame; i++) - { - m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); - m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); - } - - for ( ; ; ) - { - int dc_only_scan, refinement_scan; - pDecode_block_func decode_block_func; - - if (!init_scan()) - break; - - dc_only_scan = (m_spectral_start == 0); - refinement_scan = (m_successive_high != 0); - - if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - - if (dc_only_scan) - { - if (m_spectral_end) - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - } - else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - - if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) - stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); - - if (dc_only_scan) - { - if (refinement_scan) - decode_block_func = decode_block_dc_refine; - else - decode_block_func = decode_block_dc_first; - } - else - { - if (refinement_scan) - decode_block_func = decode_block_ac_refine; - else - decode_block_func = decode_block_ac_first; - } - - decode_scan(decode_block_func); - - m_bits_left = 16; - get_bits(16); - get_bits(16); - } - - m_comps_in_scan = m_comps_in_frame; - - for (i = 0; i < m_comps_in_frame; i++) - m_comp_list[i] = i; - - calc_mcu_block_order(); -} - -void jpeg_decoder::init_sequential() -{ - if (!init_scan()) - stop_decoding(JPGD_UNEXPECTED_MARKER); -} - -void jpeg_decoder::decode_start() -{ - init_frame(); - - if (m_progressive_flag) - init_progressive(); - else - init_sequential(); -} - -void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream) -{ - init(pStream); - locate_sof_marker(); -} - -jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream) -{ - if (setjmp(m_jmp_state)) - return; - decode_init(pStream); -} - -int jpeg_decoder::begin_decoding() -{ - if (m_ready_flag) - return JPGD_SUCCESS; - - if (m_error_code) - return JPGD_FAILED; - - if (setjmp(m_jmp_state)) - return JPGD_FAILED; - - decode_start(); - - m_ready_flag = true; - - return JPGD_SUCCESS; -} - -jpeg_decoder::~jpeg_decoder() -{ - free_all_blocks(); -} - -jpeg_decoder_file_stream::jpeg_decoder_file_stream() -{ - m_pFile = NULL; - m_eof_flag = false; - m_error_flag = false; -} - -void jpeg_decoder_file_stream::close() -{ - if (m_pFile) - { - fclose(m_pFile); - m_pFile = NULL; - } - - m_eof_flag = false; - m_error_flag = false; -} - -jpeg_decoder_file_stream::~jpeg_decoder_file_stream() -{ - close(); -} - -bool jpeg_decoder_file_stream::open(const char *Pfilename) -{ - close(); - - m_eof_flag = false; - m_error_flag = false; + y += 64 * 6 - 64 * 2; + c += 64 * 6 - 8; + } + } + + uint32_t jpeg_decoder::H2V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 6; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; + + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 256; + const int y1_base = (c_y1 & 7) * 8 + 256; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + + static const uint8_t s_muls[2][2][4] = + { + { { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, }, + { { 3, 1, 9, 3 }, { 9, 3, 3, 1 } } + }; + + if (((row & 15) >= 1) && ((row & 15) <= 14)) + { + assert((row & 1) == 1); + assert(((y + 1 - 1) >> 1) == c_y0); + + assert(p_YSamples == m_pSample_buf); + assert(p_C0Samples == m_pSample_buf); + + uint8* d1 = m_pScan_line_1; + const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7); + int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + if (((x & 1) == 1) && (x < m_image_x_size - 1)) + { + const int nx = x + 1; + assert(c_x0 == (nx - 1) >> 1); + + k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7); + y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + ++x; + } + } + + return 2; + } + else + { + for (int x = 0; x < m_image_x_size; x++) + { + int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + + return 1; + } + } + + // Y (1 block per MCU) to 8-bit grayscale + void jpeg_decoder::gray_convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + *(uint*)d = *(uint*)s; + *(uint*)(&d[4]) = *(uint*)(&s[4]); + + s += 64; + d += 8; + } + } + + // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. + void jpeg_decoder::find_eoi() + { + if (!m_progressive_flag) + { + // Attempt to read the EOI marker. + //get_bits_no_markers(m_bits_left & 7); + + // Prime the bit buffer + m_bits_left = 16; + get_bits(16); + get_bits(16); + + // The next marker _should_ be EOI + process_markers(); + } + + m_total_bytes_read -= m_in_buf_left; + } + + int jpeg_decoder::decode_next_mcu_row() + { + if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + if (chroma_y_filtering) + { + std::swap(m_pSample_buf, m_pSample_buf_prev); + + m_sample_buf_prev_valid = true; + } + + if (m_progressive_flag) + load_next_row(); + else + decode_next_row(); + + // Find the EOI marker if that was the last row. + if (m_total_lines_left <= m_max_mcu_y_size) + find_eoi(); + + m_mcu_lines_left = m_max_mcu_y_size; + return 0; + } + + int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) + { + if ((m_error_code) || (!m_ready_flag)) + return JPGD_FAILED; + + if (m_total_lines_left == 0) + return JPGD_DONE; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + + bool get_another_mcu_row = false; + bool got_mcu_early = false; + if (chroma_y_filtering) + { + if (m_total_lines_left == m_image_y_size) + get_another_mcu_row = true; + else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1)) + { + get_another_mcu_row = true; + got_mcu_early = true; + } + } + else + { + get_another_mcu_row = (m_mcu_lines_left == 0); + } + + if (get_another_mcu_row) + { + int status = decode_next_mcu_row(); + if (status != 0) + return status; + } + + switch (m_scan_type) + { + case JPGD_YH2V2: + { + if ((m_flags & cFlagBoxChromaFiltering) == 0) + { + if (m_num_buffered_scanlines == 1) + { + *pScan_line = m_pScan_line_1; + } + else if (m_num_buffered_scanlines == 0) + { + m_num_buffered_scanlines = H2V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + + m_num_buffered_scanlines--; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H2V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH2V1: + { + if ((m_flags & cFlagBoxChromaFiltering) == 0) + H2V1ConvertFiltered(); + else + H2V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_YH1V2: + { + if (chroma_y_filtering) + { + H1V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H1V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH1V1: + { + H1V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_GRAYSCALE: + { + gray_convert(); + *pScan_line = m_pScan_line_0; + + break; + } + } + + *pScan_line_len = m_real_dest_bytes_per_scan_line; + + if (!got_mcu_early) + { + m_mcu_lines_left--; + } + + m_total_lines_left--; + + return JPGD_SUCCESS; + } + + // Creates the tables needed for efficient Huffman decoding. + void jpeg_decoder::make_huff_table(int index, huff_tables* pH) + { + int p, i, l, si; + uint8 huffsize[258]; + uint huffcode[258]; + uint code; + uint subtree; + int code_size; + int lastp; + int nextfreeentry; + int currententry; + + pH->ac_table = m_huff_ac[index] != 0; + + p = 0; + + for (l = 1; l <= 16; l++) + { + for (i = 1; i <= m_huff_num[index][l]; i++) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffsize[p++] = static_cast<uint8>(l); + } + } + + assert(p < 258); + huffsize[p] = 0; + + lastp = p; + + code = 0; + si = huffsize[0]; + p = 0; + + while (huffsize[p]) + { + while (huffsize[p] == si) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffcode[p++] = code; + code++; + } + + code <<= 1; + si++; + } + + memset(pH->look_up, 0, sizeof(pH->look_up)); + memset(pH->look_up2, 0, sizeof(pH->look_up2)); + memset(pH->tree, 0, sizeof(pH->tree)); + memset(pH->code_size, 0, sizeof(pH->code_size)); + + nextfreeentry = -1; + + p = 0; + + while (p < lastp) + { + i = m_huff_val[index][p]; + + code = huffcode[p]; + code_size = huffsize[p]; + + assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + pH->code_size[i] = static_cast<uint8>(code_size); + + if (code_size <= 8) + { + code <<= (8 - code_size); + + for (l = 1 << (8 - code_size); l > 0; l--) + { + if (code >= 256) + stop_decoding(JPGD_DECODE_ERROR); + + pH->look_up[code] = i; + + bool has_extrabits = false; + int extra_bits = 0; + int num_extra_bits = i & 15; + + int bits_to_fetch = code_size; + if (num_extra_bits) + { + int total_codesize = code_size + num_extra_bits; + if (total_codesize <= 8) + { + has_extrabits = true; + extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); + + if (extra_bits > 0x7FFF) + stop_decoding(JPGD_DECODE_ERROR); + + bits_to_fetch += num_extra_bits; + } + } + + if (!has_extrabits) + pH->look_up2[code] = i | (bits_to_fetch << 8); + else + pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); + + code++; + } + } + else + { + subtree = (code >> (code_size - 8)) & 0xFF; + + currententry = pH->look_up[subtree]; + + if (currententry == 0) + { + pH->look_up[subtree] = currententry = nextfreeentry; + pH->look_up2[subtree] = currententry = nextfreeentry; + + nextfreeentry -= 2; + } + + code <<= (16 - (code_size - 8)); + + for (l = code_size; l > 9; l--) + { + if ((code & 0x8000) == 0) + currententry--; + + unsigned int idx = -currententry - 1; + + if (idx >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + if (pH->tree[idx] == 0) + { + pH->tree[idx] = nextfreeentry; + + currententry = nextfreeentry; + + nextfreeentry -= 2; + } + else + { + currententry = pH->tree[idx]; + } + + code <<= 1; + } + + if ((code & 0x8000) == 0) + currententry--; + + if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + pH->tree[-currententry - 1] = i; + } + + p++; + } + } + + // Verifies the quantization tables needed for this scan are available. + void jpeg_decoder::check_quant_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr) + stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); + } + + // Verifies that all the Huffman tables needed for this scan are available. + void jpeg_decoder::check_huff_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + { + if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + + if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + } + + for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) + if (m_huff_num[i]) + { + if (!m_pHuff_tabs[i]) + m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables)); + + make_huff_table(i, m_pHuff_tabs[i]); + } + } + + // Determines the component order inside each MCU. + // Also calcs how many MCU's are on each row, etc. + bool jpeg_decoder::calc_mcu_block_order() + { + int component_num, component_id; + int max_h_samp = 0, max_v_samp = 0; + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + if (m_comp_h_samp[component_id] > max_h_samp) + max_h_samp = m_comp_h_samp[component_id]; + + if (m_comp_v_samp[component_id] > max_v_samp) + max_v_samp = m_comp_v_samp[component_id]; + } + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; + m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; + } + + if (m_comps_in_scan == 1) + { + m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; + m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; + } + else + { + m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; + m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; + } + + if (m_comps_in_scan == 1) + { + m_mcu_org[0] = m_comp_list[0]; + + m_blocks_per_mcu = 1; + } + else + { + m_blocks_per_mcu = 0; + + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + int num_blocks; + + component_id = m_comp_list[component_num]; + + num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; + + while (num_blocks--) + m_mcu_org[m_blocks_per_mcu++] = component_id; + } + } + + if (m_blocks_per_mcu > m_max_blocks_per_mcu) + return false; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + int comp_id = m_mcu_org[mcu_block]; + if (comp_id >= JPGD_MAX_QUANT_TABLES) + return false; + } + + return true; + } + + // Starts a new scan. + int jpeg_decoder::init_scan() + { + if (!locate_sos_marker()) + return JPGD_FALSE; + + if (!calc_mcu_block_order()) + return JPGD_FALSE; + + check_huff_tables(); + + check_quant_tables(); + + memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + if (m_restart_interval) + { + m_restarts_left = m_restart_interval; + m_next_restart_num = 0; + } + + fix_in_buffer(); + + return JPGD_TRUE; + } + + // Starts a frame. Determines if the number of components or sampling factors + // are supported. + void jpeg_decoder::init_frame() + { + int i; + + if (m_comps_in_frame == 1) + { + if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + m_scan_type = JPGD_GRAYSCALE; + m_max_blocks_per_mcu = 1; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if (m_comps_in_frame == 3) + { + if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || + ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1))) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH1V1; + + m_max_blocks_per_mcu = 3; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH2V1; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH1V2; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 16; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH2V2; + m_max_blocks_per_mcu = 6; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 16; + } + else + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + } + else + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; + m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; + + // These values are for the *destination* pixels: after conversion. + if (m_scan_type == JPGD_GRAYSCALE) + m_dest_bytes_per_pixel = 1; + else + m_dest_bytes_per_pixel = 4; + + m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; + + m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); + + // Initialize two scan line buffers. + m_pScan_line_0 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true); + if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) + m_pScan_line_1 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true); + + m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; + + // Should never happen + if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) + stop_decoding(JPGD_DECODE_ERROR); + + // Allocate the coefficient buffer, enough for one MCU + m_pMCU_coefficients = (jpgd_block_coeff_t *)alloc_aligned(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_coeff_t)); + + for (i = 0; i < m_max_blocks_per_mcu; i++) + m_mcu_block_max_zag[i] = 64; + + m_pSample_buf = (uint8*)alloc_aligned(m_max_blocks_per_row * 64); + m_pSample_buf_prev = (uint8*)alloc_aligned(m_max_blocks_per_row * 64); + + m_total_lines_left = m_image_y_size; + + m_mcu_lines_left = 0; + + create_look_ups(); + } + + // The coeff_buf series of methods originally stored the coefficients + // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache + // was used to make this process more efficient. Now, we can store the entire + // thing in RAM. + jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) + { + coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); + + cb->block_num_x = block_num_x; + cb->block_num_y = block_num_y; + cb->block_len_x = block_len_x; + cb->block_len_y = block_len_y; + cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_coeff_t); + cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true); + return cb; + } + + inline jpgd_block_coeff_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y) + { + if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y)) + stop_decoding(JPGD_DECODE_ERROR); + + return (jpgd_block_coeff_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); + } + + // The following methods decode the various types of m_blocks encountered + // in progressively encoded images. + void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, r; + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) + { + if (s >= 16) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + } + + pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low); + } + + void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + if (pD->get_bits_no_markers(1)) + { + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + p[0] |= (1 << pD->m_successive_low); + } + } + + void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int k, s, r; + + if (pD->m_eob_run) + { + pD->m_eob_run--; + return; + } + + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if ((k += r) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low); + } + else + { + if (r == 15) + { + if ((k += 15) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + } + else + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + pD->m_eob_run--; + + break; + } + } + } + } + + void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, k, r; + + int p1 = 1 << pD->m_successive_low; + + //int m1 = (-1) << pD->m_successive_low; + int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low)); + + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + if (pD->m_spectral_end > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + k = pD->m_spectral_start; + + if (pD->m_eob_run == 0) + { + for (; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if (s != 1) + pD->stop_decoding(JPGD_DECODE_ERROR); + + if (pD->get_bits_no_markers(1)) + s = p1; + else + s = m1; + } + else + { + if (r != 15) + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + break; + } + } + + do + { + jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1); + } + } + } + else + { + if (--r < 0) + break; + } + + k++; + + } while (k <= pD->m_spectral_end); + + if ((s) && (k < 64)) + { + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s); + } + } + } + + if (pD->m_eob_run > 0) + { + for (; k <= pD->m_spectral_end; k++) + { + jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1); + } + } + } + } + + pD->m_eob_run--; + } + } + + // Decode a scan in a progressively encoded image. + void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) + { + int mcu_row, mcu_col, mcu_block; + int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_y_mcu, 0, sizeof(block_y_mcu)); + + for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) + { + int component_num, component_id; + + memset(block_x_mcu, 0, sizeof(block_x_mcu)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + + decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs); + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + m_restarts_left--; + } + + if (m_comps_in_scan == 1) + block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + } + + // Decode a progressively encoded image. + void jpeg_decoder::init_progressive() + { + int i; + + if (m_comps_in_frame == 4) + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + // Allocate the coefficient buffers. + for (i = 0; i < m_comps_in_frame; i++) + { + m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); + m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); + } + + // See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + uint32_t total_scans = 0; + const uint32_t MAX_SCANS_TO_PROCESS = 1000; + + for (; ; ) + { + int dc_only_scan, refinement_scan; + pDecode_block_func decode_block_func; + + if (!init_scan()) + break; + + dc_only_scan = (m_spectral_start == 0); + refinement_scan = (m_successive_high != 0); + + if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if (dc_only_scan) + { + if (m_spectral_end) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } + else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) + stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); + + if (dc_only_scan) + { + if (refinement_scan) + decode_block_func = decode_block_dc_refine; + else + decode_block_func = decode_block_dc_first; + } + else + { + if (refinement_scan) + decode_block_func = decode_block_ac_refine; + else + decode_block_func = decode_block_ac_first; + } + + decode_scan(decode_block_func); + + m_bits_left = 16; + get_bits(16); + get_bits(16); + + total_scans++; + if (total_scans > MAX_SCANS_TO_PROCESS) + stop_decoding(JPGD_TOO_MANY_SCANS); + } + + m_comps_in_scan = m_comps_in_frame; + + for (i = 0; i < m_comps_in_frame; i++) + m_comp_list[i] = i; + + if (!calc_mcu_block_order()) + stop_decoding(JPGD_DECODE_ERROR); + } + + void jpeg_decoder::init_sequential() + { + if (!init_scan()) + stop_decoding(JPGD_UNEXPECTED_MARKER); + } + + void jpeg_decoder::decode_start() + { + init_frame(); + + if (m_progressive_flag) + init_progressive(); + else + init_sequential(); + } + + void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags) + { + init(pStream, flags); + locate_sof_marker(); + } + + jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags) + { + if (::setjmp(m_jmp_state)) + return; + decode_init(pStream, flags); + } + + int jpeg_decoder::begin_decoding() + { + if (m_ready_flag) + return JPGD_SUCCESS; + + if (m_error_code) + return JPGD_FAILED; + + if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); + + m_ready_flag = true; + + return JPGD_SUCCESS; + } + + jpeg_decoder::~jpeg_decoder() + { + free_all_blocks(); + } + + jpeg_decoder_file_stream::jpeg_decoder_file_stream() + { + m_pFile = nullptr; + m_eof_flag = false; + m_error_flag = false; + } + + void jpeg_decoder_file_stream::close() + { + if (m_pFile) + { + fclose(m_pFile); + m_pFile = nullptr; + } + + m_eof_flag = false; + m_error_flag = false; + } + + jpeg_decoder_file_stream::~jpeg_decoder_file_stream() + { + close(); + } + + bool jpeg_decoder_file_stream::open(const char* Pfilename) + { + close(); + + m_eof_flag = false; + m_error_flag = false; #if defined(_MSC_VER) - m_pFile = NULL; - fopen_s(&m_pFile, Pfilename, "rb"); + m_pFile = nullptr; + fopen_s(&m_pFile, Pfilename, "rb"); #else - m_pFile = fopen(Pfilename, "rb"); + m_pFile = fopen(Pfilename, "rb"); #endif - return m_pFile != NULL; -} - -int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) -{ - if (!m_pFile) - return -1; - - if (m_eof_flag) - { - *pEOF_flag = true; - return 0; - } - - if (m_error_flag) - return -1; - - int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); - if (bytes_read < max_bytes_to_read) - { - if (ferror(m_pFile)) - { - m_error_flag = true; - return -1; - } - - m_eof_flag = true; - *pEOF_flag = true; - } - - return bytes_read; -} - -bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size) -{ - close(); - m_pSrc_data = pSrc_data; - m_ofs = 0; - m_size = size; - return true; -} - -int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) -{ - *pEOF_flag = false; - - if (!m_pSrc_data) - return -1; - - uint bytes_remaining = m_size - m_ofs; - if ((uint)max_bytes_to_read > bytes_remaining) - { - max_bytes_to_read = bytes_remaining; - *pEOF_flag = true; - } - - memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); - m_ofs += max_bytes_to_read; - - return max_bytes_to_read; -} - -unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps) -{ - if (!actual_comps) - return NULL; - *actual_comps = 0; - - if ((!pStream) || (!width) || (!height) || (!req_comps)) - return NULL; - - if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) - return NULL; - - jpeg_decoder decoder(pStream); - if (decoder.get_error_code() != JPGD_SUCCESS) - return NULL; - - const int image_width = decoder.get_width(), image_height = decoder.get_height(); - *width = image_width; - *height = image_height; - *actual_comps = decoder.get_num_components(); - - if (decoder.begin_decoding() != JPGD_SUCCESS) - return NULL; - - const int dst_bpl = image_width * req_comps; - - uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); - if (!pImage_data) - return NULL; - - for (int y = 0; y < image_height; y++) - { - const uint8* pScan_line; - uint scan_line_len; - if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) - { - jpgd_free(pImage_data); - return NULL; - } - - uint8 *pDst = pImage_data + y * dst_bpl; - - if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) - memcpy(pDst, pScan_line, dst_bpl); - else if (decoder.get_num_components() == 1) - { - if (req_comps == 3) - { - for (int x = 0; x < image_width; x++) - { - uint8 luma = pScan_line[x]; - pDst[0] = luma; - pDst[1] = luma; - pDst[2] = luma; - pDst += 3; - } - } - else - { - for (int x = 0; x < image_width; x++) - { - uint8 luma = pScan_line[x]; - pDst[0] = luma; - pDst[1] = luma; - pDst[2] = luma; - pDst[3] = 255; - pDst += 4; - } - } - } - else if (decoder.get_num_components() == 3) - { - if (req_comps == 1) - { - const int YR = 19595, YG = 38470, YB = 7471; - for (int x = 0; x < image_width; x++) - { - int r = pScan_line[x*4+0]; - int g = pScan_line[x*4+1]; - int b = pScan_line[x*4+2]; - *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16); - } - } - else - { - for (int x = 0; x < image_width; x++) - { - pDst[0] = pScan_line[x*4+0]; - pDst[1] = pScan_line[x*4+1]; - pDst[2] = pScan_line[x*4+2]; - pDst += 3; - } - } - } - } - - return pImage_data; -} - -unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps) -{ - jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); - return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps); -} - -unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps) -{ - jpgd::jpeg_decoder_file_stream file_stream; - if (!file_stream.open(pSrc_filename)) - return NULL; - return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps); -} - -} // namespace jpgd
\ No newline at end of file + return m_pFile != nullptr; + } + + int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + if (!m_pFile) + return -1; + + if (m_eof_flag) + { + *pEOF_flag = true; + return 0; + } + + if (m_error_flag) + return -1; + + int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); + if (bytes_read < max_bytes_to_read) + { + if (ferror(m_pFile)) + { + m_error_flag = true; + return -1; + } + + m_eof_flag = true; + *pEOF_flag = true; + } + + return bytes_read; + } + + bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size) + { + close(); + m_pSrc_data = pSrc_data; + m_ofs = 0; + m_size = size; + return true; + } + + int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + *pEOF_flag = false; + + if (!m_pSrc_data) + return -1; + + uint bytes_remaining = m_size - m_ofs; + if ((uint)max_bytes_to_read > bytes_remaining) + { + max_bytes_to_read = bytes_remaining; + *pEOF_flag = true; + } + + memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); + m_ofs += max_bytes_to_read; + + return max_bytes_to_read; + } + + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + if (!actual_comps) + return nullptr; + *actual_comps = 0; + + if ((!pStream) || (!width) || (!height) || (!req_comps)) + return nullptr; + + if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) + return nullptr; + + jpeg_decoder decoder(pStream, flags); + if (decoder.get_error_code() != JPGD_SUCCESS) + return nullptr; + + const int image_width = decoder.get_width(), image_height = decoder.get_height(); + *width = image_width; + *height = image_height; + *actual_comps = decoder.get_num_components(); + + if (decoder.begin_decoding() != JPGD_SUCCESS) + return nullptr; + + const int dst_bpl = image_width * req_comps; + + uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); + if (!pImage_data) + return nullptr; + + for (int y = 0; y < image_height; y++) + { + const uint8* pScan_line; + uint scan_line_len; + if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) + { + jpgd_free(pImage_data); + return nullptr; + } + + uint8* pDst = pImage_data + y * dst_bpl; + + if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) + memcpy(pDst, pScan_line, dst_bpl); + else if (decoder.get_num_components() == 1) + { + if (req_comps == 3) + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst += 3; + } + } + else + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst[3] = 255; + pDst += 4; + } + } + } + else if (decoder.get_num_components() == 3) + { + if (req_comps == 1) + { + const int YR = 19595, YG = 38470, YB = 7471; + for (int x = 0; x < image_width; x++) + { + int r = pScan_line[x * 4 + 0]; + int g = pScan_line[x * 4 + 1]; + int b = pScan_line[x * 4 + 2]; + *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16); + } + } + else + { + for (int x = 0; x < image_width; x++) + { + pDst[0] = pScan_line[x * 4 + 0]; + pDst[1] = pScan_line[x * 4 + 1]; + pDst[2] = pScan_line[x * 4 + 2]; + pDst += 3; + } + } + } + } + + return pImage_data; + } + + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); + return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags); + } + + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_file_stream file_stream; + if (!file_stream.open(pSrc_filename)) + return nullptr; + return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags); + } + +} // namespace jpgd diff --git a/thirdparty/jpeg-compressor/jpgd.h b/thirdparty/jpeg-compressor/jpgd.h index 150b9a0b26..39136696ba 100644 --- a/thirdparty/jpeg-compressor/jpgd.h +++ b/thirdparty/jpeg-compressor/jpgd.h @@ -1,319 +1,351 @@ // jpgd.h - C++ class for JPEG decompression. -// Public domain, Rich Geldreich <richgel99@gmail.com> +// Richard Geldreich <richgel99@gmail.com> +// See jpgd.cpp for license (Public Domain or Apache 2.0). #ifndef JPEG_DECODER_H #define JPEG_DECODER_H #include <stdlib.h> #include <stdio.h> #include <setjmp.h> +#include <assert.h> +#include <stdint.h> #ifdef _MSC_VER - #define JPGD_NORETURN __declspec(noreturn) +#define JPGD_NORETURN __declspec(noreturn) #elif defined(__GNUC__) - #define JPGD_NORETURN __attribute__ ((noreturn)) +#define JPGD_NORETURN __attribute__ ((noreturn)) #else - #define JPGD_NORETURN +#define JPGD_NORETURN #endif +#define JPGD_HUFF_TREE_MAX_LENGTH 512 +#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256 + namespace jpgd { - typedef unsigned char uint8; - typedef signed short int16; - typedef unsigned short uint16; - typedef unsigned int uint; - typedef signed int int32; - - // Loads a JPEG image from a memory buffer or a file. - // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). - // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). - // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. - // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. - unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps); - unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps); - - // Success/failure error codes. - enum jpgd_status - { - JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, - JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, - JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, - JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, - JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, - JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, - JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, - JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR, - JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM - }; - - // Input stream interface. - // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. - // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. - // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. - // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. - class jpeg_decoder_stream - { - public: - jpeg_decoder_stream() { } - virtual ~jpeg_decoder_stream() { } - - // The read() method is called when the internal input buffer is empty. - // Parameters: - // pBuf - input buffer - // max_bytes_to_read - maximum bytes that can be written to pBuf - // pEOF_flag - set this to true if at end of stream (no more bytes remaining) - // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). - // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0; - }; - - // stdio FILE stream class. - class jpeg_decoder_file_stream : public jpeg_decoder_stream - { - jpeg_decoder_file_stream(const jpeg_decoder_file_stream &); - jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &); - - FILE *m_pFile; - bool m_eof_flag, m_error_flag; - - public: - jpeg_decoder_file_stream(); - virtual ~jpeg_decoder_file_stream(); - - bool open(const char *Pfilename); - void close(); - - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); - }; - - // Memory stream class. - class jpeg_decoder_mem_stream : public jpeg_decoder_stream - { - const uint8 *m_pSrc_data; - uint m_ofs, m_size; - - public: - jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } - jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } - - virtual ~jpeg_decoder_mem_stream() { } - - bool open(const uint8 *pSrc_data, uint size); - void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } - - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); - }; - - // Loads JPEG file from a jpeg_decoder_stream. - unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps); - - enum - { - JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, - JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384 - }; - - typedef int16 jpgd_quant_t; - typedef int16 jpgd_block_t; - - class jpeg_decoder - { - public: - // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. - // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. - jpeg_decoder(jpeg_decoder_stream *pStream); - - ~jpeg_decoder(); - - // Call this method after constructing the object to begin decompression. - // If JPGD_SUCCESS is returned you may then call decode() on each scanline. - int begin_decoding(); - - // Returns the next scan line. - // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). - // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). - // Returns JPGD_SUCCESS if a scan line has been returned. - // Returns JPGD_DONE if all scan lines have been returned. - // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. - int decode(const void** pScan_line, uint* pScan_line_len); - - inline jpgd_status get_error_code() const { return m_error_code; } - - inline int get_width() const { return m_image_x_size; } - inline int get_height() const { return m_image_y_size; } - - inline int get_num_components() const { return m_comps_in_frame; } - - inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } - inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } - - // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). - inline int get_total_bytes_read() const { return m_total_bytes_read; } - - private: - jpeg_decoder(const jpeg_decoder &); - jpeg_decoder &operator =(const jpeg_decoder &); - - typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int); - - struct huff_tables - { - bool ac_table; - uint look_up[256]; - uint look_up2[256]; - uint8 code_size[256]; - uint tree[512]; - }; - - struct coeff_buf - { - uint8 *pData; - int block_num_x, block_num_y; - int block_len_x, block_len_y; - int block_size; - }; - - struct mem_block - { - mem_block *m_pNext; - size_t m_used_count; - size_t m_size; - char m_data[1]; - }; - - jmp_buf m_jmp_state; - mem_block *m_pMem_blocks; - int m_image_x_size; - int m_image_y_size; - jpeg_decoder_stream *m_pStream; - int m_progressive_flag; - uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; - uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size - uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size - jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables - int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) - int m_comps_in_frame; // # of components in frame - int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor - int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor - int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector - int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID - int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; - int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; - int m_comps_in_scan; // # of components in scan - int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan - int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector - int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector - int m_spectral_start; // spectral selection start - int m_spectral_end; // spectral selection end - int m_successive_low; // successive approximation low - int m_successive_high; // successive approximation high - int m_max_mcu_x_size; // MCU's max. X size in pixels - int m_max_mcu_y_size; // MCU's max. Y size in pixels - int m_blocks_per_mcu; - int m_max_blocks_per_row; - int m_mcus_per_row, m_mcus_per_col; - int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; - int m_total_lines_left; // total # lines left in image - int m_mcu_lines_left; // total # lines left in this MCU - int m_real_dest_bytes_per_scan_line; - int m_dest_bytes_per_scan_line; // rounded up - int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) - huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; - coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; - coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; - int m_eob_run; - int m_block_y_mcu[JPGD_MAX_COMPONENTS]; - uint8* m_pIn_buf_ofs; - int m_in_buf_left; - int m_tem_flag; - bool m_eof_flag; - uint8 m_in_buf_pad_start[128]; - uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; - uint8 m_in_buf_pad_end[128]; - int m_bits_left; - uint m_bit_buf; - int m_restart_interval; - int m_restarts_left; - int m_next_restart_num; - int m_max_mcus_per_row; - int m_max_blocks_per_mcu; - int m_expanded_blocks_per_mcu; - int m_expanded_blocks_per_row; - int m_expanded_blocks_per_component; - bool m_freq_domain_chroma_upsample; - int m_max_mcus_per_col; - uint m_last_dc_val[JPGD_MAX_COMPONENTS]; - jpgd_block_t* m_pMCU_coefficients; - int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; - uint8* m_pSample_buf; - int m_crr[256]; - int m_cbb[256]; - int m_crg[256]; - int m_cbg[256]; - uint8* m_pScan_line_0; - uint8* m_pScan_line_1; - jpgd_status m_error_code; - bool m_ready_flag; - int m_total_bytes_read; - - void free_all_blocks(); - JPGD_NORETURN void stop_decoding(jpgd_status status); - void *alloc(size_t n, bool zero = false); - void word_clear(void *p, uint16 c, uint n); - void prep_in_buffer(); - void read_dht_marker(); - void read_dqt_marker(); - void read_sof_marker(); - void skip_variable_marker(); - void read_dri_marker(); - void read_sos_marker(); - int next_marker(); - int process_markers(); - void locate_soi_marker(); - void locate_sof_marker(); - int locate_sos_marker(); - void init(jpeg_decoder_stream * pStream); - void create_look_ups(); - void fix_in_buffer(); - void transform_mcu(int mcu_row); - void transform_mcu_expand(int mcu_row); - coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); - inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y); - void load_next_row(); - void decode_next_row(); - void make_huff_table(int index, huff_tables *pH); - void check_quant_tables(); - void check_huff_tables(); - void calc_mcu_block_order(); - int init_scan(); - void init_frame(); - void process_restart(); - void decode_scan(pDecode_block_func decode_block_func); - void init_progressive(); - void init_sequential(); - void decode_start(); - void decode_init(jpeg_decoder_stream * pStream); - void H2V2Convert(); - void H2V1Convert(); - void H1V2Convert(); - void H1V1Convert(); - void gray_convert(); - void expanded_convert(); - void find_eoi(); - inline uint get_char(); - inline uint get_char(bool *pPadding_flag); - inline void stuff_char(uint8 q); - inline uint8 get_octet(); - inline uint get_bits(int num_bits); - inline uint get_bits_no_markers(int numbits); - inline int huff_decode(huff_tables *pH); - inline int huff_decode(huff_tables *pH, int& extrabits); - static inline uint8 clamp(int i); - static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); - }; - + typedef unsigned char uint8; + typedef signed short int16; + typedef unsigned short uint16; + typedef unsigned int uint; + typedef signed int int32; + + // Loads a JPEG image from a memory buffer or a file. + // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). + // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). + // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. + // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + // Success/failure error codes. + enum jpgd_status + { + JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, + JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, + JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, + JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, + JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, + JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, + JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, + JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, + JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS + }; + + // Input stream interface. + // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. + // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. + // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. + // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. + class jpeg_decoder_stream + { + public: + jpeg_decoder_stream() { } + virtual ~jpeg_decoder_stream() { } + + // The read() method is called when the internal input buffer is empty. + // Parameters: + // pBuf - input buffer + // max_bytes_to_read - maximum bytes that can be written to pBuf + // pEOF_flag - set this to true if at end of stream (no more bytes remaining) + // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). + // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) = 0; + }; + + // stdio FILE stream class. + class jpeg_decoder_file_stream : public jpeg_decoder_stream + { + jpeg_decoder_file_stream(const jpeg_decoder_file_stream&); + jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&); + + FILE* m_pFile; + bool m_eof_flag, m_error_flag; + + public: + jpeg_decoder_file_stream(); + virtual ~jpeg_decoder_file_stream(); + + bool open(const char* Pfilename); + void close(); + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Memory stream class. + class jpeg_decoder_mem_stream : public jpeg_decoder_stream + { + const uint8* m_pSrc_data; + uint m_ofs, m_size; + + public: + jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } + jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } + + virtual ~jpeg_decoder_mem_stream() { } + + bool open(const uint8* pSrc_data, uint size); + void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Loads JPEG file from a jpeg_decoder_stream. + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + enum + { + JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, + JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768 + }; + + typedef int16 jpgd_quant_t; + typedef int16 jpgd_block_coeff_t; + + class jpeg_decoder + { + public: + enum + { + cFlagBoxChromaFiltering = 1, + cFlagDisableSIMD = 2 + }; + + // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. + // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. + jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags = 0); + + ~jpeg_decoder(); + + // Call this method after constructing the object to begin decompression. + // If JPGD_SUCCESS is returned you may then call decode() on each scanline. + + int begin_decoding(); + + // Returns the next scan line. + // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). + // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). + // Returns JPGD_SUCCESS if a scan line has been returned. + // Returns JPGD_DONE if all scan lines have been returned. + // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. + int decode(const void** pScan_line, uint* pScan_line_len); + + inline jpgd_status get_error_code() const { return m_error_code; } + + inline int get_width() const { return m_image_x_size; } + inline int get_height() const { return m_image_y_size; } + + inline int get_num_components() const { return m_comps_in_frame; } + + inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } + inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } + + // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). + inline int get_total_bytes_read() const { return m_total_bytes_read; } + + private: + jpeg_decoder(const jpeg_decoder&); + jpeg_decoder& operator =(const jpeg_decoder&); + + typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int); + + struct huff_tables + { + bool ac_table; + uint look_up[256]; + uint look_up2[256]; + uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH]; + uint tree[JPGD_HUFF_TREE_MAX_LENGTH]; + }; + + struct coeff_buf + { + uint8* pData; + int block_num_x, block_num_y; + int block_len_x, block_len_y; + int block_size; + }; + + struct mem_block + { + mem_block* m_pNext; + size_t m_used_count; + size_t m_size; + char m_data[1]; + }; + + jmp_buf m_jmp_state; + uint32_t m_flags; + mem_block* m_pMem_blocks; + int m_image_x_size; + int m_image_y_size; + jpeg_decoder_stream* m_pStream; + + int m_progressive_flag; + + uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; + uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size + uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size + jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables + int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) + int m_comps_in_frame; // # of components in frame + int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor + int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor + int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector + int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID + int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; + int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; + int m_comps_in_scan; // # of components in scan + int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan + int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector + int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector + int m_spectral_start; // spectral selection start + int m_spectral_end; // spectral selection end + int m_successive_low; // successive approximation low + int m_successive_high; // successive approximation high + int m_max_mcu_x_size; // MCU's max. X size in pixels + int m_max_mcu_y_size; // MCU's max. Y size in pixels + int m_blocks_per_mcu; + int m_max_blocks_per_row; + int m_mcus_per_row, m_mcus_per_col; + int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; + int m_total_lines_left; // total # lines left in image + int m_mcu_lines_left; // total # lines left in this MCU + int m_num_buffered_scanlines; + int m_real_dest_bytes_per_scan_line; + int m_dest_bytes_per_scan_line; // rounded up + int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) + huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; + coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; + coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; + int m_eob_run; + int m_block_y_mcu[JPGD_MAX_COMPONENTS]; + uint8* m_pIn_buf_ofs; + int m_in_buf_left; + int m_tem_flag; + + uint8 m_in_buf_pad_start[64]; + uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; + uint8 m_in_buf_pad_end[64]; + + int m_bits_left; + uint m_bit_buf; + int m_restart_interval; + int m_restarts_left; + int m_next_restart_num; + int m_max_mcus_per_row; + int m_max_blocks_per_mcu; + + int m_max_mcus_per_col; + uint m_last_dc_val[JPGD_MAX_COMPONENTS]; + jpgd_block_coeff_t* m_pMCU_coefficients; + int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; + uint8* m_pSample_buf; + uint8* m_pSample_buf_prev; + int m_crr[256]; + int m_cbb[256]; + int m_crg[256]; + int m_cbg[256]; + uint8* m_pScan_line_0; + uint8* m_pScan_line_1; + jpgd_status m_error_code; + int m_total_bytes_read; + + bool m_ready_flag; + bool m_eof_flag; + bool m_sample_buf_prev_valid; + bool m_has_sse2; + + inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; } + void free_all_blocks(); + JPGD_NORETURN void stop_decoding(jpgd_status status); + void* alloc(size_t n, bool zero = false); + void* alloc_aligned(size_t nSize, uint32_t align = 16, bool zero = false); + void word_clear(void* p, uint16 c, uint n); + void prep_in_buffer(); + void read_dht_marker(); + void read_dqt_marker(); + void read_sof_marker(); + void skip_variable_marker(); + void read_dri_marker(); + void read_sos_marker(); + int next_marker(); + int process_markers(); + void locate_soi_marker(); + void locate_sof_marker(); + int locate_sos_marker(); + void init(jpeg_decoder_stream* pStream, uint32_t flags); + void create_look_ups(); + void fix_in_buffer(); + void transform_mcu(int mcu_row); + coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); + inline jpgd_block_coeff_t* coeff_buf_getp(coeff_buf* cb, int block_x, int block_y); + void load_next_row(); + void decode_next_row(); + void make_huff_table(int index, huff_tables* pH); + void check_quant_tables(); + void check_huff_tables(); + bool calc_mcu_block_order(); + int init_scan(); + void init_frame(); + void process_restart(); + void decode_scan(pDecode_block_func decode_block_func); + void init_progressive(); + void init_sequential(); + void decode_start(); + void decode_init(jpeg_decoder_stream* pStream, uint32_t flags); + void H2V2Convert(); + uint32_t H2V2ConvertFiltered(); + void H2V1Convert(); + void H2V1ConvertFiltered(); + void H1V2Convert(); + void H1V2ConvertFiltered(); + void H1V1Convert(); + void gray_convert(); + void find_eoi(); + inline uint get_char(); + inline uint get_char(bool* pPadding_flag); + inline void stuff_char(uint8 q); + inline uint8 get_octet(); + inline uint get_bits(int num_bits); + inline uint get_bits_no_markers(int numbits); + inline int huff_decode(huff_tables* pH); + inline int huff_decode(huff_tables* pH, int& extrabits); + + // Clamps a value between 0-255. + static inline uint8 clamp(int i) + { + if (static_cast<uint>(i) > 255) + i = (((~i) >> 31) & 0xFF); + return static_cast<uint8>(i); + } + int decode_next_mcu_row(); + + static void decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + }; + } // namespace jpgd #endif // JPEG_DECODER_H diff --git a/thirdparty/jpeg-compressor/jpgd_idct.h b/thirdparty/jpeg-compressor/jpgd_idct.h new file mode 100644 index 0000000000..876425a959 --- /dev/null +++ b/thirdparty/jpeg-compressor/jpgd_idct.h @@ -0,0 +1,462 @@ +// Copyright 2009 Intel Corporation +// All Rights Reserved +// +// Permission is granted to use, copy, distribute and prepare derivative works of this +// software for any purpose and without fee, provided, that the above copyright notice +// and this statement appear in all copies. Intel makes no representations about the +// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS." +// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY, +// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE, +// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// assume any responsibility for any errors which may appear in this software nor any +// responsibility to update it. +// +// From: +// https://software.intel.com/sites/default/files/m/d/4/1/d/8/UsingIntelAVXToImplementIDCT-r1_5.pdf +// https://software.intel.com/file/29048 +// +// Requires SSE +// +#ifdef _MSC_VER +#include <intrin.h> +#endif +#include <immintrin.h> + +#ifdef _MSC_VER + #define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else + #define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#define BITS_INV_ACC 4 +#define SHIFT_INV_ROW 16 - BITS_INV_ACC +#define SHIFT_INV_COL 1 + BITS_INV_ACC +const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1) +const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1) +const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round + +JPGD_SIMD_ALIGN(short, shortM128_one_corr[8]) = {1, 1, 1, 1, 1, 1, 1, 1}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_row[8]) = {IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_col[8]) = {IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8])= {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR}; +JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5 + +//----------------------------------------------------------------------------- +// Table for rows 0,4 - constants are multiplied on cos_4_16 +// w15 w14 w11 w10 w07 w06 w03 w02 +// w29 w28 w25 w24 w21 w20 w17 w16 +// w31 w30 w27 w26 w23 w22 w19 w18 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_04[]) = { + 16384, 21407, 16384, 8867, + 16384, -8867, 16384, -21407, // w13 w12 w09 w08 + 16384, 8867, -16384, -21407, // w07 w06 w03 w02 + -16384, 21407, 16384, -8867, // w15 w14 w11 w10 + 22725, 19266, 19266, -4520, // w21 w20 w17 w16 + 12873, -22725, 4520, -12873, // w29 w28 w25 w24 + 12873, 4520, -22725, -12873, // w23 w22 w19 w18 + 4520, 19266, 19266, -22725}; // w31 w30 w27 w26 + + // Table for rows 1,7 - constants are multiplied on cos_1_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_17[]) = { + 22725, 29692, 22725, 12299, + 22725, -12299, 22725, -29692, // w13 w12 w09 w08 + 22725, 12299, -22725, -29692, // w07 w06 w03 w02 + -22725, 29692, 22725, -12299, // w15 w14 w11 w10 + 31521, 26722, 26722, -6270, // w21 w20 w17 w16 + 17855, -31521, 6270, -17855, // w29 w28 w25 w24 + 17855, 6270, -31521, -17855, // w23 w22 w19 w18 + 6270, 26722, 26722, -31521}; // w31 w30 w27 w26 + +// Table for rows 2,6 - constants are multiplied on cos_2_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_26[]) = { + 21407, 27969, 21407, 11585, + 21407, -11585, 21407, -27969, // w13 w12 w09 w08 + 21407, 11585, -21407, -27969, // w07 w06 w03 w02 + -21407, 27969, 21407, -11585, // w15 w14 w11 w10 + 29692, 25172, 25172, -5906, // w21 w20 w17 w16 + 16819, -29692, 5906, -16819, // w29 w28 w25 w24 + 16819, 5906, -29692, -16819, // w23 w22 w19 w18 + 5906, 25172, 25172, -29692}; // w31 w30 w27 w26 +// Table for rows 3,5 - constants are multiplied on cos_3_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = { + 19266, 25172, 19266, 10426, + 19266, -10426, 19266, -25172, // w13 w12 w09 w08 + 19266, 10426, -19266, -25172, // w07 w06 w03 w02 + -19266, 25172, 19266, -10426, // w15 w14 w11 w10 + 26722, 22654, 22654, -5315, // w21 w20 w17 w16 + 15137, -26722, 5315, -15137, // w29 w28 w25 w24 + 15137, 5315, -26722, -15137, // w23 w22 w19 w18 + 5315, 22654, 22654, -26722}; // w31 w30 w27 w26 + +JPGD_SIMD_ALIGN(short, shortM128_128[8]) = { 128, 128, 128, 128, 128, 128, 128, 128 }; + +void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB) +{ + __m128i r_xmm0, r_xmm4; + __m128i r_xmm1, r_xmm2, r_xmm3, r_xmm5, r_xmm6, r_xmm7; + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + short * pTab_i_04 = shortM128_tab_i_04; + short * pTab_i_26 = shortM128_tab_i_26; + + //Get pointers for this input and output + pTab_i_04 = shortM128_tab_i_04; + pTab_i_26 = shortM128_tab_i_26; + + //Row 1 and Row 3 + r_xmm0 = _mm_load_si128((__m128i *) pInput); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[2*8])); + + // *** Work on the data in xmm0 + //low shuffle mask = 0xd8 = 11 01 10 00 + //get short 2 and short 0 into ls 32-bits + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + + // copy short 2 and short 0 to all locations + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + + // add to those copies + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + + // shuffle mask = 0x55 = 01 01 01 01 + // copy short 3 and short 1 to all locations + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + + // high shuffle mask = 0xd8 = 11 01 10 00 + // get short 6 and short 4 into bit positions 64-95 + // get short 7 and short 5 into bit positions 96-127 + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + + // add to short 3 and short 1 + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + + // shuffle mask = 0xaa = 10 10 10 10 + // copy short 6 and short 4 to all locations + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + + // shuffle mask = 0xaa = 11 11 11 11 + // copy short 7 and short 5 to all locations + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + + // add to short 6 and short 4 + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + + // *** Work on the data in xmm4 + // high shuffle mask = 0xd8 11 01 10 00 + // get short 6 and short 4 into bit positions 64-95 + // get short 7 and short 5 into bit positions 96-127 + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + + // (xmm0 short 2 and short 0 plus pSi) + some constants + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row0 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row2 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 5 and row 7 + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[4*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[6*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row4 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row6 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 4 and row 2 + pTab_i_04 = shortM128_tab_i_35; + pTab_i_26 = shortM128_tab_i_17; + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[3*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[1*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row3 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row1 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 6 and row 8 + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[5*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[7*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row5 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row7 = _mm_packs_epi32(r_xmm4, r_xmm6); + + r_xmm1 = _mm_load_si128((__m128i *) shortM128_tg_3_16); + r_xmm2 = row5; + r_xmm3 = row3; + r_xmm0 = _mm_mulhi_epi16(row5, r_xmm1); + + r_xmm1 = _mm_mulhi_epi16(r_xmm1, r_xmm3); + r_xmm5 = _mm_load_si128((__m128i *) shortM128_tg_1_16); + r_xmm6 = row7; + r_xmm4 = _mm_mulhi_epi16(row7, r_xmm5); + + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm2); + r_xmm5 = _mm_mulhi_epi16(r_xmm5, row1); + r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm3); + r_xmm7 = row6; + + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm3); + r_xmm3 = _mm_load_si128((__m128i *) shortM128_tg_2_16); + r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm1); + r_xmm7 = _mm_mulhi_epi16(r_xmm7, r_xmm3); + r_xmm1 = r_xmm0; + r_xmm3 = _mm_mulhi_epi16(r_xmm3, row2); + r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm6); + r_xmm4 = _mm_adds_epi16(r_xmm4, row1); + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm4); + r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i *) shortM128_one_corr)); + r_xmm4 = _mm_subs_epi16(r_xmm4, r_xmm1); + r_xmm6 = r_xmm5; + r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm2); + r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_one_corr)); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2); + + //Intermediate results, needed later + __m128i temp3, temp7; + temp7 = r_xmm0; + + r_xmm1 = r_xmm4; + r_xmm0 = _mm_load_si128((__m128i *) shortM128_cos_4_16); + r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm5); + r_xmm2 = _mm_load_si128((__m128i *) shortM128_cos_4_16); + r_xmm2 = _mm_mulhi_epi16(r_xmm2, r_xmm4); + + //Intermediate results, needed later + temp3 = r_xmm6; + + r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm5); + r_xmm7 = _mm_adds_epi16(r_xmm7, row2); + r_xmm3 = _mm_subs_epi16(r_xmm3, row6); + r_xmm6 = row0; + r_xmm0 = _mm_mulhi_epi16(r_xmm0, r_xmm1); + r_xmm5 = row4; + r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm6); + r_xmm6 = _mm_subs_epi16(r_xmm6, row4); + r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm2); + + r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i *) shortM128_one_corr)); + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm1); + r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i *) shortM128_one_corr)); + + r_xmm2 = r_xmm5; + r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm7); + r_xmm1 = r_xmm6; + r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_round_inv_col)); + r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm7); + r_xmm7 = temp7; + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm3); + r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i *) shortM128_round_inv_col)); + r_xmm7 = _mm_adds_epi16(r_xmm7, r_xmm5); + r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL); + r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm3); + r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i *) shortM128_round_inv_corr)); + r_xmm3 = r_xmm6; + r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i *) shortM128_round_inv_corr)); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm4); + + //Store results for row 0 + //_mm_store_si128((__m128i *) pOutput, r_xmm7); + __m128i r0 = r_xmm7; + + r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL); + r_xmm7 = r_xmm1; + r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm0); + + //Store results for row 1 + //_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6); + __m128i r1 = r_xmm6; + + r_xmm1 = _mm_srai_epi16(r_xmm1, SHIFT_INV_COL); + r_xmm6 = temp3; + r_xmm7 = _mm_subs_epi16(r_xmm7, r_xmm0); + r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL); + + //Store results for row 2 + //_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1); + __m128i r2 = r_xmm1; + + r_xmm5 = _mm_subs_epi16(r_xmm5, temp7); + r_xmm5 = _mm_srai_epi16(r_xmm5, SHIFT_INV_COL); + + //Store results for row 7 + //_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5); + __m128i r7 = r_xmm5; + + r_xmm3 = _mm_subs_epi16(r_xmm3, r_xmm4); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2); + r_xmm2 = _mm_subs_epi16(r_xmm2, temp3); + r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL); + r_xmm2 = _mm_srai_epi16(r_xmm2, SHIFT_INV_COL); + + //Store results for row 3 + //_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6); + __m128i r3 = r_xmm6; + + r_xmm3 = _mm_srai_epi16(r_xmm3, SHIFT_INV_COL); + + //Store results for rows 4, 5, and 6 + //_mm_store_si128((__m128i *) (&pOutput[4*8]), r_xmm2); + //_mm_store_si128((__m128i *) (&pOutput[5*8]), r_xmm7); + //_mm_store_si128((__m128i *) (&pOutput[6*8]), r_xmm3); + + __m128i r4 = r_xmm2; + __m128i r5 = r_xmm7; + __m128i r6 = r_xmm3; + + r0 = _mm_add_epi16(*(const __m128i *)shortM128_128, r0); + r1 = _mm_add_epi16(*(const __m128i *)shortM128_128, r1); + r2 = _mm_add_epi16(*(const __m128i *)shortM128_128, r2); + r3 = _mm_add_epi16(*(const __m128i *)shortM128_128, r3); + r4 = _mm_add_epi16(*(const __m128i *)shortM128_128, r4); + r5 = _mm_add_epi16(*(const __m128i *)shortM128_128, r5); + r6 = _mm_add_epi16(*(const __m128i *)shortM128_128, r6); + r7 = _mm_add_epi16(*(const __m128i *)shortM128_128, r7); + + ((__m128i *)pOutputUB)[0] = _mm_packus_epi16(r0, r1); + ((__m128i *)pOutputUB)[1] = _mm_packus_epi16(r2, r3); + ((__m128i *)pOutputUB)[2] = _mm_packus_epi16(r4, r5); + ((__m128i *)pOutputUB)[3] = _mm_packus_epi16(r6, r7); +} diff --git a/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch new file mode 100644 index 0000000000..7b338de084 --- /dev/null +++ b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch @@ -0,0 +1,31 @@ +diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp +index a0c494db61..257d0b7574 100644 +--- a/thirdparty/jpeg-compressor/jpgd.cpp ++++ b/thirdparty/jpeg-compressor/jpgd.cpp +@@ -2126,7 +2126,7 @@ namespace jpgd { + + int jpeg_decoder::decode_next_mcu_row() + { +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); +@@ -3042,7 +3042,7 @@ namespace jpgd { + + jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags) + { +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return; + decode_init(pStream, flags); + } +@@ -3055,7 +3055,7 @@ namespace jpgd { + if (m_error_code) + return JPGD_FAILED; + +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index d076c2352f..93de091c4d 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -546,6 +546,23 @@ #error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" #endif +#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ + !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) +#error "One or more versions of the TLS protocol are enabled " \ + "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" +#endif + #if defined(MBEDTLS_SSL_PROTO_DTLS) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -669,6 +686,10 @@ #error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) +#error "MBEDTLS_CERTS_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) #error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" #endif diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 8e2ce03c32..e0a2e7f6d6 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -40,16 +40,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 5 +#define MBEDTLS_VERSION_PATCH 6 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100500 -#define MBEDTLS_VERSION_STRING "2.16.5" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.5" +#define MBEDTLS_VERSION_NUMBER 0x02100600 +#define MBEDTLS_VERSION_STRING "2.16.6" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index 040c20bd38..725e176df2 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -1938,6 +1938,20 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, final_norm: #endif + /* + * Knowledge of the jacobian coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + if( f_rng != 0 ) + MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); + MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); @@ -2308,6 +2322,20 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); } + /* + * Knowledge of the projective coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + if( f_rng != NULL ) + MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); cleanup: diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index afced7a99c..c5c3af69df 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -1417,6 +1417,19 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); + /* Check that there is enough room for: + * - 2 bytes of version + * - 1 byte of cookie_len + */ + if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "incoming HelloVerifyRequest message is too short" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + /* * struct { * ProtocolVersion server_version; @@ -1445,8 +1458,6 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) } cookie_len = *p++; - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); - if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, @@ -1455,6 +1466,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } + MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); mbedtls_free( ssl->handshake->verify_cookie ); diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index b8f35fec5d..cbec74fe8c 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -1004,8 +1004,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_init != NULL ) { - int ret = 0; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, @@ -2885,15 +2883,18 @@ static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); /* * Swap transform_out and out_ctr with the alternative ones */ -static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) +static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) { mbedtls_ssl_transform *tmp_transform; unsigned char tmp_out_ctr[8]; +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + int ret; +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ if( ssl->transform_out == ssl->handshake->alt_transform_out ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); - return; + return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); @@ -2920,7 +2921,9 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } -#endif +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + + return( 0 ); } /* @@ -2957,7 +2960,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) ssl->handshake->cur_msg = ssl->handshake->flight; ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - ssl_swap_epochs( ssl ); + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; } @@ -2980,7 +2984,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); - ssl_swap_epochs( ssl ); + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); } ret = ssl_get_remaining_payload_in_datagram( ssl ); @@ -3017,7 +3022,10 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) { if( is_finished ) - ssl_swap_epochs( ssl ); + { + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); + } if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) return( ret ); @@ -3997,17 +4005,23 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { + int send_ret; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); + MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", + ssl->out_buf, len ); /* Don't check write errors as we can't do anything here. * If the error is permanent we'll catch it later, * if it's not, then hopefully it'll work next time. */ - (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); + (void) send_ret; return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); } if( ret == 0 ) { - /* Got a valid cookie, partially reset context */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 2e0b0e8f6c..4d25303206 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -1063,7 +1063,7 @@ cleanup: mbedtls_x509_crt_free( &clicert ); #else ((void) verbose); -#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ return( ret ); } |