diff options
643 files changed, 16674 insertions, 9211 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index bc56cba21b..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Bug report -about: Report a bug in Godot -title: '' -labels: '' -assignees: '' - ---- -<!-- Please search existing issues for potential duplicates before filing yours: -https://github.com/godotengine/godot/issues?q=is%3Aissue ---> - -**Godot version:** -<!-- Specify commit hash if using non-official build. --> - - -**OS/device including version:** -<!-- Specify GPU model, drivers, and the backend (GLES2, GLES3, Vulkan) if graphics-related. --> - - -**Issue description:** -<!-- What happened, and what was expected. --> - - -**Steps to reproduce:** - - -**Minimal reproduction project:** -<!-- A small Godot project which reproduces the issue. Drag and drop a zip archive to upload it. --> diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..43ba5ef357 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,56 @@ +name: Bug report +description: Report a bug in Godot +body: + +- type: markdown + attributes: + value: | + - Read our [CONTRIBUTING.md guide](CONTRIBUTING.md#reporting-bugs) on reporting bugs. + - Write a descriptive issue title above. + - Search [open](https://github.com/godotengine/godot/issues) and [closed](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. + - Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html). + +- type: input + attributes: + label: Godot version + description: > + Specify the Git commit hash if using a development or non-official build. + If you use a custom build, please test if your issue is reproducible in official builds too. + placeholder: 3.3.stable, 4.0.dev (3041becc6) + validations: + required: true + +- type: input + attributes: + label: System information + description: | + Specify the OS version, and when relevant hardware information. + For graphics-related issues, specify the GPU model, driver version, and the rendering backend (GLES2, GLES3, Vulkan). + placeholder: Windows 10, GLES3, Intel HD Graphics 620 (27.20.100.9616) + validations: + required: true + +- type: textarea + attributes: + label: Issue description + description: | + Describe your issue briefly. What doesn't work, and how do you expect it to work instead? + You can include images or videos with drag and drop, and format code blocks or logs with <code>```</code> tags. + validations: + required: true + +- type: textarea + attributes: + label: Steps to reproduce + description: | + List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them. + If you include a minimal reproduction project below, you can detail how to use it here. + validations: + required: true + +- type: textarea + attributes: + label: Minimal reproduction project + description: | + A small Godot project which reproduces the issue. Highly recommended to speed up troubleshooting. + Drag and drop a ZIP archive to upload it. diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 2dad253288..63930aa9e2 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -6,7 +6,6 @@ env: GODOT_BASE_BRANCH: master SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 - ANDROID_NDK_VERSION: 21.4.7075529 jobs: android-template: @@ -29,10 +28,6 @@ jobs: with: java-version: 8 - - name: Install Android NDK - run: | - sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install 'ndk;${{env.ANDROID_NDK_VERSION}}' - # Upload cache on completion and check it out now - name: Load .scons_cache directory id: android-template-cache @@ -64,7 +59,6 @@ jobs: - name: Compilation env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ - ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/${{env.ANDROID_NDK_VERSION}}/ run: | scons target=release tools=no android_arch=armv7 scons target=release tools=no android_arch=arm64v8 diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 53d13f7429..9baec79d43 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1102,7 +1102,7 @@ ProjectSettings::ProjectSettings() { if (Engine::get_singleton()->has_singleton("GodotSharp")) { extensions.push_back("cs"); } - extensions.push_back("shader"); + extensions.push_back("gdshader"); GLOBAL_DEF("editor/run/main_run_args", ""); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 05265c41ad..ed4387a1b9 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1225,7 +1225,7 @@ Error _File::open(const String &p_path, ModeFlags p_mode_flags) { Error err; f = FileAccess::open(p_path, p_mode_flags, &err); if (f) { - f->set_endian_swap(eswap); + f->set_big_endian(big_endian); } return err; } @@ -1381,15 +1381,15 @@ Vector<String> _File::get_csv_line(const String &p_delim) const { * These flags get reset to false (little endian) on each open */ -void _File::set_endian_swap(bool p_swap) { - eswap = p_swap; +void _File::set_big_endian(bool p_big_endian) { + big_endian = p_big_endian; if (f) { - f->set_endian_swap(p_swap); + f->set_big_endian(p_big_endian); } } -bool _File::get_endian_swap() { - return eswap; +bool _File::is_big_endian() { + return big_endian; } Error _File::get_error() const { @@ -1551,8 +1551,8 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text); ClassDB::bind_method(D_METHOD("get_md5", "path"), &_File::get_md5); ClassDB::bind_method(D_METHOD("get_sha256", "path"), &_File::get_sha256); - ClassDB::bind_method(D_METHOD("get_endian_swap"), &_File::get_endian_swap); - ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap); + ClassDB::bind_method(D_METHOD("is_big_endian"), &_File::is_big_endian); + ClassDB::bind_method(D_METHOD("set_big_endian", "big_endian"), &_File::set_big_endian); ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error); ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &_File::get_var, DEFVAL(false)); @@ -1575,7 +1575,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("file_exists", "path"), &_File::file_exists); ClassDB::bind_method(D_METHOD("get_modified_time", "file"), &_File::get_modified_time); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "endian_swap"), "set_endian_swap", "get_endian_swap"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian"); BIND_ENUM_CONSTANT(READ); BIND_ENUM_CONSTANT(WRITE); diff --git a/core/core_bind.h b/core/core_bind.h index 8253040a12..d05353bf0f 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -356,7 +356,7 @@ class _File : public Reference { GDCLASS(_File, Reference); FileAccess *f = nullptr; - bool eswap = false; + bool big_endian = false; protected: static void _bind_methods(); @@ -413,13 +413,13 @@ public: String get_md5(const String &p_path) const; String get_sha256(const String &p_path) const; - /* Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac). + /* + * Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac). * It's not about the current CPU type but file formats. - * This flags get reset to false (little endian) on each open. + * This flag gets reset to `false` (little endian) on each open. */ - - void set_endian_swap(bool p_swap); - bool get_endian_swap(); + void set_big_endian(bool p_big_endian); + bool is_big_endian(); Error get_error() const; // Get last error. diff --git a/core/core_constants.cpp b/core/core_constants.cpp index a0a41015dc..7fc09fc3a6 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -580,10 +580,10 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUATERNION", Variant::QUATERNION); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM3D", Variant::TRANSFORM3D); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); diff --git a/core/input/input.cpp b/core/input/input.cpp index 6eafec087d..6e98b596d7 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -85,7 +85,7 @@ Input *Input::get_singleton() { } void Input::set_mouse_mode(MouseMode p_mode) { - ERR_FAIL_INDEX((int)p_mode, 4); + ERR_FAIL_INDEX((int)p_mode, 5); set_mouse_mode_func(p_mode); } @@ -138,6 +138,7 @@ void Input::_bind_methods() { BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED); BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED); + BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN); BIND_ENUM_CONSTANT(CURSOR_ARROW); BIND_ENUM_CONSTANT(CURSOR_IBEAM); diff --git a/core/input/input.h b/core/input/input.h index 99b45db325..ecb4981b13 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -46,7 +46,8 @@ public: MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED + MOUSE_MODE_CONFINED, + MOUSE_MODE_CONFINED_HIDDEN, }; #undef CursorShape diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index b9514c8c8b..9e316291e8 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -257,6 +257,7 @@ Error FileAccessEncrypted::get_error() const { void FileAccessEncrypted::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); + ERR_FAIL_COND(!p_src && p_length > 0); if (pos < get_length()) { for (uint64_t i = 0; i < p_length; i++) { diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 0114ab1765..d9be2a4a75 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -168,6 +168,7 @@ void FileAccessMemory::store_8(uint8_t p_byte) { } void FileAccessMemory::store_buffer(const uint8_t *p_src, uint64_t p_length) { + ERR_FAIL_COND(!p_src && p_length > 0); uint64_t left = length - pos; uint64_t write = MIN(p_length, left); if (write < p_length) { diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e9983ece47..7b43daf9c0 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -320,9 +320,9 @@ uint64_t FileAccessPack::get_buffer(uint8_t *p_dst, uint64_t p_length) const { return to_read; } -void FileAccessPack::set_endian_swap(bool p_swap) { - FileAccess::set_endian_swap(p_swap); - f->set_endian_swap(p_swap); +void FileAccessPack::set_big_endian(bool p_big_endian) { + FileAccess::set_big_endian(p_big_endian); + f->set_big_endian(p_big_endian); } Error FileAccessPack::get_error() const { diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 9747e865c8..7a83fc938f 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -171,7 +171,7 @@ public: virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; - virtual void set_endian_swap(bool p_swap); + virtual void set_big_endian(bool p_big_endian); virtual Error get_error() const; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index de37ba87dd..001b1c4757 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -118,7 +118,6 @@ IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { _resolve_hostname(res, p_hostname, p_type); resolver->cache[key] = res; } - resolver->mutex.unlock(); for (int i = 0; i < res.size(); ++i) { if (res[i].is_valid()) { @@ -129,7 +128,7 @@ IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { } Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) { - resolver->mutex.lock(); + MutexLock lock(resolver->mutex); String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); if (!resolver->cache.has(key)) { @@ -137,7 +136,6 @@ Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) { } List<IPAddress> res = resolver->cache[key]; - resolver->mutex.unlock(); Array result; for (int i = 0; i < res.size(); ++i) { @@ -184,7 +182,6 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const { if (resolver->queue[p_id].status.get() == IP::RESOLVER_STATUS_NONE) { ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE"); - resolver->mutex.unlock(); return IP::RESOLVER_STATUS_NONE; } return resolver->queue[p_id].status.get(); @@ -197,14 +194,11 @@ IPAddress IP::get_resolve_item_address(ResolverID p_id) const { if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); - resolver->mutex.unlock(); return IPAddress(); } List<IPAddress> res = resolver->queue[p_id].response; - resolver->mutex.unlock(); - for (int i = 0; i < res.size(); ++i) { if (res[i].is_valid()) { return res[i]; @@ -215,19 +209,15 @@ IPAddress IP::get_resolve_item_address(ResolverID p_id) const { Array IP::get_resolve_item_addresses(ResolverID p_id) const { ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, Array()); - - resolver->mutex.lock(); + MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); - resolver->mutex.unlock(); return Array(); } List<IPAddress> res = resolver->queue[p_id].response; - resolver->mutex.unlock(); - Array result; for (int i = 0; i < res.size(); ++i) { if (res[i].is_valid()) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 0282609270..18e1092c26 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -279,9 +279,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; - case Variant::QUAT: { + case Variant::QUATERNION: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); - Quat val; + Quaternion val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); @@ -325,9 +325,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { ERR_FAIL_COND_V(len < 4 * 12, ERR_INVALID_DATA); - Transform val; + Transform3D val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); @@ -889,7 +889,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo // Test for potential wrong values sent by the debugger when it breaks. Object *obj = p_variant.get_validated_object(); if (!obj) { - // Object is invalid, send a nullptr instead. + // Object is invalid, send a nullptr instead. if (buf) { encode_uint32(Variant::NIL, buf); } @@ -1099,9 +1099,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4; } break; - case Variant::QUAT: { + case Variant::QUATERNION: { if (buf) { - Quat q = p_variant; + Quaternion q = p_variant; encode_float(q.x, &buf[0]); encode_float(q.y, &buf[4]); encode_float(q.z, &buf[8]); @@ -1138,9 +1138,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 9 * 4; } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { if (buf) { - Transform val = p_variant; + Transform3D val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { memcpy(&buf[(i * 3 + j) * 4], &val.basis.elements[i][j], sizeof(float)); diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index fda4083804..78ec7ea21a 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -44,6 +44,56 @@ #include "core/os/os.h" #endif +String _get_rpc_md5(const Node *p_node) { + String rpc_list; + const Vector<MultiplayerAPI::RPCConfig> node_config = p_node->get_node_rpc_methods(); + for (int i = 0; i < node_config.size(); i++) { + rpc_list += String(node_config[i].name); + } + if (p_node->get_script_instance()) { + const Vector<MultiplayerAPI::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); + for (int i = 0; i < script_config.size(); i++) { + rpc_list += String(script_config[i].name); + } + } + return rpc_list.md5_text(); +} + +const MultiplayerAPI::RPCConfig _get_rpc_config(const Node *p_node, const StringName &p_method, uint16_t &r_id) { + const Vector<MultiplayerAPI::RPCConfig> node_config = p_node->get_node_rpc_methods(); + for (int i = 0; i < node_config.size(); i++) { + if (node_config[i].name == p_method) { + r_id = ((uint16_t)i) & (1 << 15); + return node_config[i]; + } + } + if (p_node->get_script_instance()) { + const Vector<MultiplayerAPI::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); + for (int i = 0; i < script_config.size(); i++) { + if (script_config[i].name == p_method) { + r_id = (uint16_t)i; + return script_config[i]; + } + } + } + return MultiplayerAPI::RPCConfig(); +} + +const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_id) { + Vector<MultiplayerAPI::RPCConfig> config; + uint16_t id = p_id; + if (id & (1 << 15)) { + id = id & ~(1 << 15); + config = p_node->get_node_rpc_methods(); + } else { + config = p_node->get_script_instance()->get_rpc_methods(); + } + if (id < config.size()) { + return config[p_id]; + } + return MultiplayerAPI::RPCConfig(); +} + _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) { switch (mode) { case MultiplayerAPI::RPC_MODE_DISABLED: { @@ -231,8 +281,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ _process_confirm_path(p_from, p_packet, p_packet_len); } break; - case NETWORK_COMMAND_REMOTE_CALL: - case NETWORK_COMMAND_REMOTE_SET: { + case NETWORK_COMMAND_REMOTE_CALL: { // Extract packet meta int packet_min_size = 1; int name_id_offset = 1; @@ -302,13 +351,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ } const int packet_len = get_packet_len(node_target, p_packet_len); - if (packet_type == NETWORK_COMMAND_REMOTE_CALL) { - _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size); - - } else { - _process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size); - } - + _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size); } break; case NETWORK_COMMAND_RAW: { @@ -362,16 +405,11 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small."); // Check that remote can call the RPC on this node. - StringName name = p_node->get_node_rpc_method(p_rpc_method_id); - RPCMode rpc_mode = p_node->get_node_rpc_mode_by_id(p_rpc_method_id); - if (name == StringName() && p_node->get_script_instance()) { - name = p_node->get_script_instance()->get_rpc_method(p_rpc_method_id); - rpc_mode = p_node->get_script_instance()->get_rpc_mode_by_id(p_rpc_method_id); - } - ERR_FAIL_COND(name == StringName()); + const RPCConfig config = _get_rpc_config_by_id(p_node, p_rpc_method_id); + ERR_FAIL_COND(config.name == StringName()); - bool can_call = _can_call_mode(p_node, rpc_mode, p_from); - ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); + bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from); + ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); int argc = 0; bool byte_only = false; @@ -424,47 +462,14 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, Callable::CallError ce; - p_node->call(name, (const Variant **)argp.ptr(), argc, ce); + p_node->call(config.name, (const Variant **)argp.ptr(), argc, ce); if (ce.error != Callable::CallError::CALL_OK) { - String error = Variant::get_call_error_text(p_node, name, (const Variant **)argp.ptr(), argc, ce); + String error = Variant::get_call_error_text(p_node, config.name, (const Variant **)argp.ptr(), argc, ce); error = "RPC - " + error; ERR_PRINT(error); } } -void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) { - ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); - - // Check that remote can call the RSET on this node. - StringName name = p_node->get_node_rset_property(p_rpc_property_id); - RPCMode rset_mode = p_node->get_node_rset_mode_by_id(p_rpc_property_id); - if (name == StringName() && p_node->get_script_instance()) { - name = p_node->get_script_instance()->get_rset_property(p_rpc_property_id); - rset_mode = p_node->get_script_instance()->get_rset_mode_by_id(p_rpc_property_id); - } - ERR_FAIL_COND(name == StringName()); - - bool can_call = _can_call_mode(p_node, rset_mode, p_from); - ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + "."); - -#ifdef DEBUG_ENABLED - _profile_node_data("in_rset", p_node->get_instance_id()); -#endif - - Variant value; - Error err = _decode_and_decompress_variant(value, &p_packet[p_offset], p_packet_len - p_offset, nullptr); - - ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RSET value."); - - bool valid; - - p_node->set(name, value, &valid); - if (!valid) { - String error = "Error setting remote property '" + String(name) + "', not found in object of type " + p_node->get_class() + "."; - ERR_PRINT(error); - } -} - void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) { ERR_FAIL_COND_MSG(p_packet_len < 38, "Invalid packet received. Size too small."); int ofs = 1; @@ -487,7 +492,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, Node *node = root_node->get_node(path); ERR_FAIL_COND(node == nullptr); - const bool valid_rpc_checksum = node->get_rpc_md5() == methods_md5; + const bool valid_rpc_checksum = _get_rpc_md5(node) == methods_md5; if (valid_rpc_checksum == false) { ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path); } @@ -569,7 +574,7 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC const int path_len = encode_cstring(path.get_data(), nullptr); // Extract MD5 from rpc methods list. - const String methods_md5 = p_node->get_rpc_md5(); + const String methods_md5 = _get_rpc_md5(p_node); const int methods_md5_len = 33; // 32 + 1 for the `0` that is added by the encoder. Vector<uint8_t> packet; @@ -752,7 +757,7 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u return OK; } -void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) { +void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree."); ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree."); @@ -797,7 +802,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p // - `NetworkNameIdCompression` in the next 1 bit. // - `byte_only_or_no_args` in the next 1 bit. // - So we still have the last bit free! - uint8_t command_type = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL; + uint8_t command_type = NETWORK_COMMAND_REMOTE_CALL; uint8_t node_id_compression = UINT8_MAX; uint8_t name_id_compression = UINT8_MAX; bool byte_only_or_no_args = false; @@ -837,81 +842,42 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p ofs += 4; } - if (p_set) { - // Take the rpc property ID - uint16_t property_id = p_from->get_node_rset_property_id(p_name); - if (property_id == UINT16_MAX && p_from->get_script_instance()) { - property_id = p_from->get_script_instance()->get_rset_property_id(p_name); - } - ERR_FAIL_COND_MSG(property_id == UINT16_MAX, "Unable to take the `property_id` for the property:" + p_name + ". This can only happen if this property is not marked as `remote`."); - - if (property_id <= UINT8_MAX) { - // The ID fits in 1 byte - name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = static_cast<uint8_t>(property_id); - ofs += 1; - } else { - // The ID is larger, let's use 2 bytes - name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; - MAKE_ROOM(ofs + 2); - encode_uint16(property_id, &(packet_cache.write[ofs])); - ofs += 2; - } - - // Set argument. - int len(0); - Error err = _encode_and_compress_variant(*p_arg[0], nullptr, len); - ERR_FAIL_COND_MSG(err != OK, "Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!"); - MAKE_ROOM(ofs + len); - _encode_and_compress_variant(*p_arg[0], &(packet_cache.write[ofs]), len); - ofs += len; - + // Encode method ID + if (p_rpc_id <= UINT8_MAX) { + // The ID fits in 1 byte + name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; + MAKE_ROOM(ofs + 1); + packet_cache.write[ofs] = static_cast<uint8_t>(p_rpc_id); + ofs += 1; } else { - // Take the rpc method ID - uint16_t method_id = p_from->get_node_rpc_method_id(p_name); - if (method_id == UINT16_MAX && p_from->get_script_instance()) { - method_id = p_from->get_script_instance()->get_rpc_method_id(p_name); - } - ERR_FAIL_COND_MSG(method_id == UINT16_MAX, - vformat("Unable to take the `method_id` for the function \"%s\" at path: \"%s\". This happens when the method is not marked as `remote`.", p_name, p_from->get_path())); - - if (method_id <= UINT8_MAX) { - // The ID fits in 1 byte - name_id_compression = NETWORK_NAME_ID_COMPRESSION_8; - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = static_cast<uint8_t>(method_id); - ofs += 1; - } else { - // The ID is larger, let's use 2 bytes - name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; - MAKE_ROOM(ofs + 2); - encode_uint16(method_id, &(packet_cache.write[ofs])); - ofs += 2; - } + // The ID is larger, let's use 2 bytes + name_id_compression = NETWORK_NAME_ID_COMPRESSION_16; + MAKE_ROOM(ofs + 2); + encode_uint16(p_rpc_id, &(packet_cache.write[ofs])); + ofs += 2; + } - if (p_argcount == 0) { - byte_only_or_no_args = true; - } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) { - byte_only_or_no_args = true; - // Special optimization when only the byte vector is sent. - const Vector<uint8_t> data = *p_arg[0]; - MAKE_ROOM(ofs + data.size()); - memcpy(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size()); - ofs += data.size(); - } else { - // Arguments - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = p_argcount; - ofs += 1; - for (int i = 0; i < p_argcount; i++) { - int len(0); - Error err = _encode_and_compress_variant(*p_arg[i], nullptr, len); - ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); - MAKE_ROOM(ofs + len); - _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); - ofs += len; - } + if (p_argcount == 0) { + byte_only_or_no_args = true; + } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) { + byte_only_or_no_args = true; + // Special optimization when only the byte vector is sent. + const Vector<uint8_t> data = *p_arg[0]; + MAKE_ROOM(ofs + data.size()); + memcpy(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size()); + ofs += data.size(); + } else { + // Arguments + MAKE_ROOM(ofs + 1); + packet_cache.write[ofs] = p_argcount; + ofs += 1; + for (int i = 0; i < p_argcount; i++) { + int len(0); + Error err = _encode_and_compress_variant(*p_arg[i], nullptr, len); + ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); + MAKE_ROOM(ofs + len); + _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); + ofs += len; } } @@ -927,7 +893,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p #endif // Take chance and set transfer mode, since all send methods will use it. - network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE); + network_peer->set_transfer_mode(p_config.transfer_mode); if (has_all_peers) { // They all have verified paths, so send fast. @@ -1015,19 +981,15 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const bool call_local_native = false; bool call_local_script = false; bool is_master = p_node->is_network_master(); - + uint16_t rpc_id = UINT16_MAX; + const RPCConfig config = _get_rpc_config(p_node, p_method, rpc_id); + ERR_FAIL_COND_MSG(config.name == StringName(), + vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is not marked for RPCs.", p_method, p_node->get_path())); if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { - // Check that send mode can use local call. - - RPCMode rpc_mode = p_node->get_node_rpc_mode(p_method); - call_local_native = _should_call_local(rpc_mode, is_master, skip_rpc); - - if (call_local_native) { - // Done below. - } else if (p_node->get_script_instance()) { - // Attempt with script. - rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method); - call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc); + if (rpc_id & (1 << 15)) { + call_local_native = _should_call_local(config.rpc_mode, is_master, skip_rpc); + } else { + call_local_script = _should_call_local(config.rpc_mode, is_master, skip_rpc); } } @@ -1036,7 +998,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const _profile_node_data("out_rpc", p_node->get_instance_id()); #endif - _send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount); + _send_rpc(p_node, p_peer_id, rpc_id, config, p_method, p_arg, p_argcount); } if (call_local_native) { @@ -1071,70 +1033,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode."); } -void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) { - ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to RSET while no network peer is active."); - ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to RSET on a node which is not inside SceneTree."); - ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to send an RSET via a network peer which is not connected."); - - int node_id = network_peer->get_unique_id(); - bool is_master = p_node->is_network_master(); - bool skip_rset = node_id == p_peer_id; - bool set_local = false; - - if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { - // Check that send mode can use local call. - RPCMode rpc_mode = p_node->get_node_rset_mode(p_property); - set_local = _should_call_local(rpc_mode, is_master, skip_rset); - - if (set_local) { - bool valid; - int temp_id = rpc_sender_id; - - rpc_sender_id = get_network_unique_id(); - p_node->set(p_property, p_value, &valid); - rpc_sender_id = temp_id; - - if (!valid) { - String error = "rset() aborted in local set, property not found: - " + String(p_property) + "."; - ERR_PRINT(error); - return; - } - } else if (p_node->get_script_instance()) { - // Attempt with script. - rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property); - - set_local = _should_call_local(rpc_mode, is_master, skip_rset); - - if (set_local) { - int temp_id = rpc_sender_id; - - rpc_sender_id = get_network_unique_id(); - bool valid = p_node->get_script_instance()->set(p_property, p_value); - rpc_sender_id = temp_id; - - if (!valid) { - String error = "rset() aborted in local script set, property not found: - " + String(p_property) + "."; - ERR_PRINT(error); - return; - } - } - } - } - - if (skip_rset) { - ERR_FAIL_COND_MSG(!set_local, "RSET for '" + p_property + "' on yourself is not allowed by selected mode."); - return; - } - -#ifdef DEBUG_ENABLED - _profile_node_data("out_rset", p_node->get_instance_id()); -#endif - - const Variant *vptr = &p_value; - - _send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1); -} - Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) { ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active."); diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index 7f88b53a27..6a251cf77b 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -37,6 +37,35 @@ class MultiplayerAPI : public Reference { GDCLASS(MultiplayerAPI, Reference); +public: + enum RPCMode { + RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) + RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers + RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote + RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets + RPC_MODE_REMOTESYNC, // Using rpc() on it will call method in all remote peers and locally + RPC_MODE_MASTERSYNC, // Using rpc() on it will call method in the master peer and locally + RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method in all puppets peers and locally + }; + + struct RPCConfig { + StringName name; + RPCMode rpc_mode = RPC_MODE_DISABLED; + NetworkedMultiplayerPeer::TransferMode transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; + int channel = 0; + + bool operator==(RPCConfig const &p_other) const { + return name == p_other.name; + } + }; + + struct SortRPCConfig { + StringName::AlphCompare compare; + bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { + return compare(p_a.name, p_b.name); + } + }; + private: //path sent caches struct PathSentCache { @@ -72,10 +101,9 @@ protected: void _process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len); Node *_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len); void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); - void _process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); - void _send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount); + void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); bool _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target); Error _encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len); @@ -84,7 +112,6 @@ protected: public: enum NetworkCommands { NETWORK_COMMAND_REMOTE_CALL = 0, - NETWORK_COMMAND_REMOTE_SET, NETWORK_COMMAND_SIMPLIFY_PATH, NETWORK_COMMAND_CONFIRM_PATH, NETWORK_COMMAND_RAW, @@ -101,16 +128,6 @@ public: NETWORK_NAME_ID_COMPRESSION_16, }; - enum RPCMode { - RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) - RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers - RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote - RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets - RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally - RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally - RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally - }; - void poll(); void clear(); void set_root_node(Node *p_node); @@ -121,8 +138,6 @@ public: // Called by Node.rpc void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount); - // Called by Node.rset - void rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value); void _add_peer(int p_id); void _del_peer(int p_id); diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index 52169987fd..cf6a0b6027 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -227,10 +227,10 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd case Variant::VECTOR3: case Variant::TRANSFORM2D: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::BASIS: - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: case Variant::PACKED_BYTE_ARRAY: case Variant::PACKED_INT32_ARRAY: case Variant::PACKED_INT64_ARRAY: diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 50c9b2371a..385f15c0cf 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -51,7 +51,7 @@ enum { VARIANT_RECT2 = 11, VARIANT_VECTOR3 = 12, VARIANT_PLANE = 13, - VARIANT_QUAT = 14, + VARIANT_QUATERNION = 14, VARIANT_AABB = 15, VARIANT_MATRIX3 = 16, VARIANT_TRANSFORM = 17, @@ -199,8 +199,8 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.d = f->get_real(); r_v = v; } break; - case VARIANT_QUAT: { - Quat v; + case VARIANT_QUATERNION: { + Quaternion v; v.x = f->get_real(); v.y = f->get_real(); v.z = f->get_real(); @@ -245,7 +245,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case VARIANT_TRANSFORM: { - Transform v; + Transform3D v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); v.basis.elements[0].z = f->get_real(); @@ -851,7 +851,7 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { bool big_endian = f->get_32(); bool use_real64 = f->get_32(); - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -948,7 +948,7 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) { bool big_endian = f->get_32(); f->get_32(); // use_real64 - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); f->get_32(); // ver_minor @@ -1097,13 +1097,13 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons bool big_endian = f->get_32(); bool use_real64 = f->get_32(); - f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian #ifdef BIG_ENDIAN_ENABLED fw->store_32(!big_endian); #else fw->store_32(big_endian); #endif - fw->set_endian_swap(big_endian != 0); + fw->set_big_endian(big_endian != 0); fw->store_32(use_real64); //use real64 uint32_t ver_major = f->get_32(); @@ -1371,9 +1371,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_real(val.d); } break; - case Variant::QUAT: { - f->store_32(VARIANT_QUAT); - Quat val = p_property; + case Variant::QUATERNION: { + f->store_32(VARIANT_QUATERNION); + Quaternion val = p_property; f->store_real(val.x); f->store_real(val.y); f->store_real(val.z); @@ -1416,9 +1416,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_real(val.elements[2].z); } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { f->store_32(VARIANT_TRANSFORM); - Transform val = p_property; + Transform3D val = p_property; f->store_real(val.basis.elements[0].x); f->store_real(val.basis.elements[0].y); f->store_real(val.basis.elements[0].z); @@ -1798,7 +1798,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p if (big_endian) { f->store_32(1); - f->set_endian_swap(true); + f->set_big_endian(true); } else { f->store_32(0); } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index b942c30086..b48c48b1bc 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -354,7 +354,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & ThreadLoadTask &load_task = thread_load_tasks[local_path]; - if (load_task.resource.is_null()) { //needs to be loaded in thread + if (load_task.resource.is_null()) { //needs to be loaded in thread load_task.semaphore = memnew(Semaphore); if (thread_loading_count < thread_load_max) { diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 74154321b3..ee5e9eca0c 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -108,8 +108,8 @@ Array StreamPeer::_get_partial_data(int p_bytes) { return ret; } -void StreamPeer::set_big_endian(bool p_enable) { - big_endian = p_enable; +void StreamPeer::set_big_endian(bool p_big_endian) { + big_endian = p_big_endian; } bool StreamPeer::is_big_endian_enabled() const { diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index dadedbd2dc..1e1a3e890c 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -58,7 +58,7 @@ public: virtual int get_available_bytes() const = 0; - void set_big_endian(bool p_enable); + void set_big_endian(bool p_big_endian); bool is_big_endian_enabled() const; void put_8(int8_t p_val); diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 847edf958d..c323301eac 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -80,7 +80,6 @@ private: Vector<Attribute> attributes; - String _replace_special_characters(const String &origstr); bool _set_text(char *start, char *end); void _parse_closing_xml_element(); void _ignore_definition(); diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 037378b9d7..7489da34d9 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -345,12 +345,12 @@ void Basis::rotate(const Vector3 &p_euler) { *this = rotated(p_euler); } -Basis Basis::rotated(const Quat &p_quat) const { - return Basis(p_quat) * (*this); +Basis Basis::rotated(const Quaternion &p_quaternion) const { + return Basis(p_quaternion) * (*this); } -void Basis::rotate(const Quat &p_quat) { - *this = rotated(p_quat); +void Basis::rotate(const Quaternion &p_quaternion) { + *this = rotated(p_quaternion); } Vector3 Basis::get_rotation_euler() const { @@ -367,7 +367,7 @@ Vector3 Basis::get_rotation_euler() const { return m.get_euler(); } -Quat Basis::get_rotation_quat() const { +Quaternion Basis::get_rotation_quaternion() const { // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). // See the comment in get_scale() for further information. @@ -378,7 +378,7 @@ Quat Basis::get_rotation_quat() const { m.scale(Vector3(-1, -1, -1)); } - return m.get_quat(); + return m.get_quaternion(); } void Basis::get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const { @@ -770,9 +770,9 @@ Basis::operator String() const { return mtx; } -Quat Basis::get_quat() const { +Quaternion Basis::get_quaternion() const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_rotation(), Quat(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead."); + ERR_FAIL_COND_V_MSG(!is_rotation(), Quaternion(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quaternion() or call orthonormalized() instead."); #endif /* Allow getting a quaternion from an unnormalized transform */ Basis m = *this; @@ -803,7 +803,7 @@ Quat Basis::get_quat() const { temp[k] = (m.elements[k][i] + m.elements[i][k]) * s; } - return Quat(temp[0], temp[1], temp[2], temp[3]); + return Quaternion(temp[0], temp[1], temp[2], temp[3]); } static const Basis _ortho_bases[24] = { @@ -945,13 +945,13 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { r_angle = angle; } -void Basis::set_quat(const Quat &p_quat) { - real_t d = p_quat.length_squared(); +void Basis::set_quaternion(const Quaternion &p_quaternion) { + real_t d = p_quaternion.length_squared(); real_t s = 2.0 / d; - real_t xs = p_quat.x * s, ys = p_quat.y * s, zs = p_quat.z * s; - real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs; - real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs; - real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs; + real_t xs = p_quaternion.x * s, ys = p_quaternion.y * s, zs = p_quaternion.z * s; + real_t wx = p_quaternion.w * xs, wy = p_quaternion.w * ys, wz = p_quaternion.w * zs; + real_t xx = p_quaternion.x * xs, xy = p_quaternion.x * ys, xz = p_quaternion.x * zs; + real_t yy = p_quaternion.y * ys, yz = p_quaternion.y * zs, zz = p_quaternion.z * zs; set(1.0 - (yy + zz), xy - wz, xz + wy, xy + wz, 1.0 - (xx + zz), yz - wx, xz - wy, yz + wx, 1.0 - (xx + yy)); @@ -997,9 +997,9 @@ void Basis::set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale) { rotate(p_euler); } -void Basis::set_quat_scale(const Quat &p_quat, const Vector3 &p_scale) { +void Basis::set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_diagonal(p_scale); - rotate(p_quat); + rotate(p_quaternion); } void Basis::set_diagonal(const Vector3 &p_diag) { @@ -1018,8 +1018,8 @@ void Basis::set_diagonal(const Vector3 &p_diag) { Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const { //consider scale - Quat from(*this); - Quat to(p_to); + Quaternion from(*this); + Quaternion to(p_to); Basis b(from.slerp(to, p_weight)); b.elements[0] *= Math::lerp(elements[0].length(), p_to.elements[0].length(), p_weight); diff --git a/core/math/basis.h b/core/math/basis.h index 56f6227313..3736047dd3 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -31,7 +31,7 @@ #ifndef BASIS_H #define BASIS_H -#include "core/math/quat.h" +#include "core/math/quaternion.h" #include "core/math/vector3.h" class Basis { @@ -79,13 +79,13 @@ public: void rotate(const Vector3 &p_euler); Basis rotated(const Vector3 &p_euler) const; - void rotate(const Quat &p_quat); - Basis rotated(const Quat &p_quat) const; + void rotate(const Quaternion &p_quaternion); + Basis rotated(const Quaternion &p_quaternion) const; Vector3 get_rotation_euler() const; void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const; void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const; - Quat get_rotation_quat() const; + Quaternion get_rotation_quaternion() const; Vector3 get_rotation() const { return get_rotation_euler(); }; Vector3 rotref_posscale_decomposition(Basis &rotref) const; @@ -108,8 +108,8 @@ public: Vector3 get_euler_zyx() const; void set_euler_zyx(const Vector3 &p_euler); - Quat get_quat() const; - void set_quat(const Quat &p_quat); + Quaternion get_quaternion() const; + void set_quaternion(const Quaternion &p_quaternion); Vector3 get_euler() const { return get_euler_yxz(); } void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); } @@ -132,7 +132,7 @@ public: void set_axis_angle_scale(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale); void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale); - void set_quat_scale(const Quat &p_quat, const Vector3 &p_scale); + void set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale); // transposed dot products _FORCE_INLINE_ real_t tdotx(const Vector3 &v) const { @@ -240,10 +240,10 @@ public: #endif Basis diagonalize(); - operator Quat() const { return get_quat(); } + operator Quaternion() const { return get_quaternion(); } - Basis(const Quat &p_quat) { set_quat(p_quat); }; - Basis(const Quat &p_quat, const Vector3 &p_scale) { set_quat_scale(p_quat, p_scale); } + Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); }; + Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); } Basis(const Vector3 &p_euler) { set_euler(p_euler); } Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); } diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 1066cf5e30..66c18f7b3c 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -315,8 +315,8 @@ Vector2 CameraMatrix::get_far_plane_half_extents() const { return Vector2(res.x, res.y); } -bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const { - Vector<Plane> planes = get_projection_planes(Transform()); +bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { + Vector<Plane> planes = get_projection_planes(Transform3D()); const Planes intersections[8][3] = { { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, { PLANE_FAR, PLANE_LEFT, PLANE_BOTTOM }, @@ -338,7 +338,7 @@ bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8point return true; } -Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) const { +Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const { /** Fast Plane Extraction from combined modelview/projection matrices. * References: * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html @@ -707,8 +707,8 @@ void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { matrix[3][3] = 1; } -CameraMatrix::operator Transform() const { - Transform tr; +CameraMatrix::operator Transform3D() const { + Transform3D tr; const real_t *m = &matrix[0][0]; tr.basis.elements[0][0] = m[0]; @@ -730,8 +730,8 @@ CameraMatrix::operator Transform() const { return tr; } -CameraMatrix::CameraMatrix(const Transform &p_transform) { - const Transform &tr = p_transform; +CameraMatrix::CameraMatrix(const Transform3D &p_transform) { + const Transform3D &tr = p_transform; real_t *m = &matrix[0][0]; m[0] = tr.basis.elements[0][0]; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 3f327d3bc4..786d46055a 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -32,7 +32,7 @@ #define CAMERA_MATRIX_H #include "core/math/rect2.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" struct CameraMatrix { enum Planes { @@ -71,9 +71,9 @@ struct CameraMatrix { real_t get_fov() const; bool is_orthogonal() const; - Vector<Plane> get_projection_planes(const Transform &p_transform) const; + Vector<Plane> get_projection_planes(const Transform3D &p_transform) const; - bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const; + bool get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const; Vector2 get_viewport_half_extents() const; Vector2 get_far_plane_half_extents() const; @@ -90,7 +90,7 @@ struct CameraMatrix { void scale_translate_to_fit(const AABB &p_aabb); void make_scale(const Vector3 &p_scale); int get_pixels_per_meter(int p_for_pixel_width) const; - operator Transform() const; + operator Transform3D() const; void flip_y(); @@ -112,7 +112,7 @@ struct CameraMatrix { float get_lod_multiplier() const; CameraMatrix(); - CameraMatrix(const Transform &p_transform); + CameraMatrix(const Transform3D &p_transform); ~CameraMatrix(); }; diff --git a/core/math/color.cpp b/core/math/color.cpp index 64abd6dd08..52f029ef4b 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -211,6 +211,14 @@ bool Color::is_equal_approx(const Color &p_color) const { return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a); } +Color Color::clamp(const Color &p_min, const Color &p_max) const { + return Color( + CLAMP(r, p_min.r, p_max.r), + CLAMP(g, p_min.g, p_max.g), + CLAMP(b, p_min.b, p_max.b), + CLAMP(a, p_min.a, p_max.a)); +} + void Color::invert() { r = 1.0 - r; g = 1.0 - g; diff --git a/core/math/color.h b/core/math/color.h index e404d80c8a..a95dbf4f60 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -89,6 +89,7 @@ struct Color { bool is_equal_approx(const Color &p_color) const; + Color clamp(const Color &p_min = Color(0, 0, 0, 0), const Color &p_max = Color(1, 1, 1, 1)) const; void invert(); Color inverted() const; diff --git a/core/math/face3.cpp b/core/math/face3.cpp index 20c316c322..9af3f868d2 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -230,7 +230,7 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const { real_t minA, maxA, minB, maxB; p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA); - project_range(axis, Transform(), minB, maxB); + project_range(axis, Transform3D(), minB, maxB); if (maxA < minB || maxB < minA) { return false; @@ -244,7 +244,7 @@ Face3::operator String() const { return String() + vertex[0] + ", " + vertex[1] + ", " + vertex[2]; } -void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void Face3::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { for (int i = 0; i < 3; i++) { Vector3 v = p_transform.xform(vertex[i]); real_t d = p_normal.dot(v); @@ -259,7 +259,7 @@ void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, } } -void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { +void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 diff --git a/core/math/face3.h b/core/math/face3.h index 2e86b0a904..5091b338ef 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -33,7 +33,7 @@ #include "core/math/aabb.h" #include "core/math/plane.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector3.h" class Face3 { @@ -74,8 +74,8 @@ public: ClockDirection get_clock_dir() const; ///< todo, test if this is returning the proper clockwisity - void get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const; - void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + void get_support(const Vector3 &p_normal, const Transform3D &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const; + void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; AABB get_aabb() const { AABB aabb(vertex[0], Vector3()); diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index 0985a727f2..570c57e254 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -88,8 +88,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } - case Variant::QUAT: { - SETUP_TYPE(Quat) + case Variant::QUATERNION: { + SETUP_TYPE(Quaternion) /**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y) @@ -141,8 +141,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } - case Variant::TRANSFORM: { - SETUP_TYPE(Transform) + case Variant::TRANSFORM3D: { + SETUP_TYPE(Transform3D) /**/ TRY_TRANSFER_FIELD("xx", basis.elements[0][0]) else TRY_TRANSFER_FIELD("xy", basis.elements[0][1]) diff --git a/core/math/quat.cpp b/core/math/quaternion.cpp index 3982a0b993..8de3d0cc2a 100644 --- a/core/math/quat.cpp +++ b/core/math/quaternion.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quat.cpp */ +/* quaternion.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "quat.h" +#include "quaternion.h" #include "core/math/basis.h" #include "core/string/print_string.h" @@ -37,7 +37,7 @@ // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. // This implementation uses XYZ convention (Z is the first rotation). -Vector3 Quat::get_euler_xyz() const { +Vector3 Quaternion::get_euler_xyz() const { Basis m(*this); return m.get_euler_xyz(); } @@ -46,7 +46,7 @@ Vector3 Quat::get_euler_xyz() const { // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. // This implementation uses YXZ convention (Z is the first rotation). -Vector3 Quat::get_euler_yxz() const { +Vector3 Quaternion::get_euler_yxz() const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized."); #endif @@ -54,7 +54,7 @@ Vector3 Quat::get_euler_yxz() const { return m.get_euler_yxz(); } -void Quat::operator*=(const Quat &p_q) { +void Quaternion::operator*=(const Quaternion &p_q) { real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y; real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z; real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x; @@ -64,45 +64,45 @@ void Quat::operator*=(const Quat &p_q) { z = zz; } -Quat Quat::operator*(const Quat &p_q) const { - Quat r = *this; +Quaternion Quaternion::operator*(const Quaternion &p_q) const { + Quaternion r = *this; r *= p_q; return r; } -bool Quat::is_equal_approx(const Quat &p_quat) const { - return Math::is_equal_approx(x, p_quat.x) && Math::is_equal_approx(y, p_quat.y) && Math::is_equal_approx(z, p_quat.z) && Math::is_equal_approx(w, p_quat.w); +bool Quaternion::is_equal_approx(const Quaternion &p_quaternion) const { + return Math::is_equal_approx(x, p_quaternion.x) && Math::is_equal_approx(y, p_quaternion.y) && Math::is_equal_approx(z, p_quaternion.z) && Math::is_equal_approx(w, p_quaternion.w); } -real_t Quat::length() const { +real_t Quaternion::length() const { return Math::sqrt(length_squared()); } -void Quat::normalize() { +void Quaternion::normalize() { *this /= length(); } -Quat Quat::normalized() const { +Quaternion Quaternion::normalized() const { return *this / length(); } -bool Quat::is_normalized() const { +bool Quaternion::is_normalized() const { return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); //use less epsilon } -Quat Quat::inverse() const { +Quaternion Quaternion::inverse() const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Quat(), "The quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The quaternion must be normalized."); #endif - return Quat(-x, -y, -z, w); + return Quaternion(-x, -y, -z, w); } -Quat Quat::slerp(const Quat &p_to, const real_t &p_weight) const { +Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Quat(), "The start quaternion must be normalized."); - ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quat(), "The end quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif - Quat to1; + Quaternion to1; real_t omega, cosom, sinom, scale0, scale1; // calc cosine @@ -137,19 +137,19 @@ Quat Quat::slerp(const Quat &p_to, const real_t &p_weight) const { scale1 = p_weight; } // calculate final values - return Quat( + return Quaternion( scale0 * x + scale1 * to1.x, scale0 * y + scale1 * to1.y, scale0 * z + scale1 * to1.z, scale0 * w + scale1 * to1.w); } -Quat Quat::slerpni(const Quat &p_to, const real_t &p_weight) const { +Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Quat(), "The start quaternion must be normalized."); - ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quat(), "The end quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif - const Quat &from = *this; + const Quaternion &from = *this; real_t dot = from.dot(p_to); @@ -162,29 +162,29 @@ Quat Quat::slerpni(const Quat &p_to, const real_t &p_weight) const { newFactor = Math::sin(p_weight * theta) * sinT, invFactor = Math::sin((1.0 - p_weight) * theta) * sinT; - return Quat(invFactor * from.x + newFactor * p_to.x, + return Quaternion(invFactor * from.x + newFactor * p_to.x, invFactor * from.y + newFactor * p_to.y, invFactor * from.z + newFactor * p_to.z, invFactor * from.w + newFactor * p_to.w); } -Quat Quat::cubic_slerp(const Quat &p_b, const Quat &p_pre_a, const Quat &p_post_b, const real_t &p_weight) const { +Quaternion Quaternion::cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const { #ifdef MATH_CHECKS - ERR_FAIL_COND_V_MSG(!is_normalized(), Quat(), "The start quaternion must be normalized."); - ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quat(), "The end quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif //the only way to do slerp :| real_t t2 = (1.0 - p_weight) * p_weight * 2; - Quat sp = this->slerp(p_b, p_weight); - Quat sq = p_pre_a.slerpni(p_post_b, p_weight); + Quaternion sp = this->slerp(p_b, p_weight); + Quaternion sq = p_pre_a.slerpni(p_post_b, p_weight); return sp.slerpni(sq, t2); } -Quat::operator String() const { +Quaternion::operator String() const { return String::num(x) + ", " + String::num(y) + ", " + String::num(z) + ", " + String::num(w); } -Quat::Quat(const Vector3 &p_axis, real_t p_angle) { +Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) { #ifdef MATH_CHECKS ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized."); #endif @@ -209,7 +209,7 @@ Quat::Quat(const Vector3 &p_axis, real_t p_angle) { // (ax, ay, az), where ax is the angle of rotation around x axis, // and similar for other axes. // This implementation uses YXZ convention (Z is the first rotation). -Quat::Quat(const Vector3 &p_euler) { +Quaternion::Quaternion(const Vector3 &p_euler) { real_t half_a1 = p_euler.y * 0.5; real_t half_a2 = p_euler.x * 0.5; real_t half_a3 = p_euler.z * 0.5; diff --git a/core/math/quat.h b/core/math/quaternion.h index d9b130c050..796214b79e 100644 --- a/core/math/quat.h +++ b/core/math/quaternion.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quat.h */ +/* quaternion.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -36,7 +36,7 @@ #include "core/math/vector3.h" #include "core/string/ustring.h" -class Quat { +class Quaternion { public: union { struct { @@ -55,21 +55,21 @@ public: return components[idx]; } _FORCE_INLINE_ real_t length_squared() const; - bool is_equal_approx(const Quat &p_quat) const; + bool is_equal_approx(const Quaternion &p_quaternion) const; real_t length() const; void normalize(); - Quat normalized() const; + Quaternion normalized() const; bool is_normalized() const; - Quat inverse() const; - _FORCE_INLINE_ real_t dot(const Quat &p_q) const; + Quaternion inverse() const; + _FORCE_INLINE_ real_t dot(const Quaternion &p_q) const; Vector3 get_euler_xyz() const; Vector3 get_euler_yxz() const; Vector3 get_euler() const { return get_euler_yxz(); }; - Quat slerp(const Quat &p_to, const real_t &p_weight) const; - Quat slerpni(const Quat &p_to, const real_t &p_weight) const; - Quat cubic_slerp(const Quat &p_b, const Quat &p_pre_a, const Quat &p_post_b, const real_t &p_weight) const; + Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const; + Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const; + Quaternion cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const; _FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { r_angle = 2 * Math::acos(w); @@ -79,11 +79,11 @@ public: r_axis.z = z * r; } - void operator*=(const Quat &p_q); - Quat operator*(const Quat &p_q) const; + void operator*=(const Quaternion &p_q); + Quaternion operator*(const Quaternion &p_q) const; - Quat operator*(const Vector3 &v) const { - return Quat(w * v.x + y * v.z - z * v.y, + Quaternion operator*(const Vector3 &v) const { + return Quaternion(w * v.x + y * v.z - z * v.y, w * v.y + z * v.x - x * v.z, w * v.z + x * v.y - y * v.x, -x * v.x - y * v.y - z * v.z); @@ -102,42 +102,42 @@ public: return inverse().xform(v); } - _FORCE_INLINE_ void operator+=(const Quat &p_q); - _FORCE_INLINE_ void operator-=(const Quat &p_q); + _FORCE_INLINE_ void operator+=(const Quaternion &p_q); + _FORCE_INLINE_ void operator-=(const Quaternion &p_q); _FORCE_INLINE_ void operator*=(const real_t &s); _FORCE_INLINE_ void operator/=(const real_t &s); - _FORCE_INLINE_ Quat operator+(const Quat &q2) const; - _FORCE_INLINE_ Quat operator-(const Quat &q2) const; - _FORCE_INLINE_ Quat operator-() const; - _FORCE_INLINE_ Quat operator*(const real_t &s) const; - _FORCE_INLINE_ Quat operator/(const real_t &s) const; + _FORCE_INLINE_ Quaternion operator+(const Quaternion &q2) const; + _FORCE_INLINE_ Quaternion operator-(const Quaternion &q2) const; + _FORCE_INLINE_ Quaternion operator-() const; + _FORCE_INLINE_ Quaternion operator*(const real_t &s) const; + _FORCE_INLINE_ Quaternion operator/(const real_t &s) const; - _FORCE_INLINE_ bool operator==(const Quat &p_quat) const; - _FORCE_INLINE_ bool operator!=(const Quat &p_quat) const; + _FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const; + _FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const; operator String() const; - _FORCE_INLINE_ Quat() {} + _FORCE_INLINE_ Quaternion() {} - _FORCE_INLINE_ Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : + _FORCE_INLINE_ Quaternion(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : x(p_x), y(p_y), z(p_z), w(p_w) { } - Quat(const Vector3 &p_axis, real_t p_angle); + Quaternion(const Vector3 &p_axis, real_t p_angle); - Quat(const Vector3 &p_euler); + Quaternion(const Vector3 &p_euler); - Quat(const Quat &p_q) : + Quaternion(const Quaternion &p_q) : x(p_q.x), y(p_q.y), z(p_q.z), w(p_q.w) { } - Quat &operator=(const Quat &p_q) { + Quaternion &operator=(const Quaternion &p_q) { x = p_q.x; y = p_q.y; z = p_q.z; @@ -145,7 +145,7 @@ public: return *this; } - Quat(const Vector3 &v0, const Vector3 &v1) // shortest arc + Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc { Vector3 c = v0.cross(v1); real_t d = v0.dot(v1); @@ -167,72 +167,72 @@ public: } }; -real_t Quat::dot(const Quat &p_q) const { +real_t Quaternion::dot(const Quaternion &p_q) const { return x * p_q.x + y * p_q.y + z * p_q.z + w * p_q.w; } -real_t Quat::length_squared() const { +real_t Quaternion::length_squared() const { return dot(*this); } -void Quat::operator+=(const Quat &p_q) { +void Quaternion::operator+=(const Quaternion &p_q) { x += p_q.x; y += p_q.y; z += p_q.z; w += p_q.w; } -void Quat::operator-=(const Quat &p_q) { +void Quaternion::operator-=(const Quaternion &p_q) { x -= p_q.x; y -= p_q.y; z -= p_q.z; w -= p_q.w; } -void Quat::operator*=(const real_t &s) { +void Quaternion::operator*=(const real_t &s) { x *= s; y *= s; z *= s; w *= s; } -void Quat::operator/=(const real_t &s) { +void Quaternion::operator/=(const real_t &s) { *this *= 1.0 / s; } -Quat Quat::operator+(const Quat &q2) const { - const Quat &q1 = *this; - return Quat(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w); +Quaternion Quaternion::operator+(const Quaternion &q2) const { + const Quaternion &q1 = *this; + return Quaternion(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w); } -Quat Quat::operator-(const Quat &q2) const { - const Quat &q1 = *this; - return Quat(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w); +Quaternion Quaternion::operator-(const Quaternion &q2) const { + const Quaternion &q1 = *this; + return Quaternion(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w); } -Quat Quat::operator-() const { - const Quat &q2 = *this; - return Quat(-q2.x, -q2.y, -q2.z, -q2.w); +Quaternion Quaternion::operator-() const { + const Quaternion &q2 = *this; + return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w); } -Quat Quat::operator*(const real_t &s) const { - return Quat(x * s, y * s, z * s, w * s); +Quaternion Quaternion::operator*(const real_t &s) const { + return Quaternion(x * s, y * s, z * s, w * s); } -Quat Quat::operator/(const real_t &s) const { +Quaternion Quaternion::operator/(const real_t &s) const { return *this * (1.0 / s); } -bool Quat::operator==(const Quat &p_quat) const { - return x == p_quat.x && y == p_quat.y && z == p_quat.z && w == p_quat.w; +bool Quaternion::operator==(const Quaternion &p_quaternion) const { + return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w; } -bool Quat::operator!=(const Quat &p_quat) const { - return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w; +bool Quaternion::operator!=(const Quaternion &p_quaternion) const { + return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w; } -_FORCE_INLINE_ Quat operator*(const real_t &p_real, const Quat &p_quat) { - return p_quat * p_real; +_FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_quaternion) { + return p_quaternion * p_real; } #endif // QUAT_H diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index fe18cc3d41..0d77bfe933 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -112,7 +112,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } } - //fourth vertex is the one most further away from the plane + //fourth vertex is the one most further away from the plane { real_t maxd = 0; diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 4a521b96ae..9189234d04 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -158,6 +158,13 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { return elements[0].is_equal_approx(p_transform.elements[0]) && elements[1].is_equal_approx(p_transform.elements[1]) && elements[2].is_equal_approx(p_transform.elements[2]); } +Transform2D Transform2D::looking_at(const Vector2 &p_target) const { + Transform2D return_trans = Transform2D(get_rotation(), get_origin()); + Vector2 target_position = affine_inverse().xform(p_target); + return_trans.set_rotation(return_trans.get_rotation() + (target_position * get_scale()).angle()); + return return_trans; +} + bool Transform2D::operator==(const Transform2D &p_transform) const { for (int i = 0; i < 3; i++) { if (elements[i] != p_transform.elements[i]) { diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 327d0f244f..715f013701 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -100,6 +100,8 @@ struct Transform2D { Transform2D orthonormalized() const; bool is_equal_approx(const Transform2D &p_transform) const; + Transform2D looking_at(const Vector2 &p_target) const; + bool operator==(const Transform2D &p_transform) const; bool operator!=(const Transform2D &p_transform) const; diff --git a/core/math/transform.cpp b/core/math/transform_3d.cpp index d4d7ff6d28..210f0b81bb 100644 --- a/core/math/transform.cpp +++ b/core/math/transform_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* transform.cpp */ +/* transform_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,54 +28,54 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "transform.h" +#include "transform_3d.h" #include "core/math/math_funcs.h" #include "core/string/print_string.h" -void Transform::affine_invert() { +void Transform3D::affine_invert() { basis.invert(); origin = basis.xform(-origin); } -Transform Transform::affine_inverse() const { - Transform ret = *this; +Transform3D Transform3D::affine_inverse() const { + Transform3D ret = *this; ret.affine_invert(); return ret; } -void Transform::invert() { +void Transform3D::invert() { basis.transpose(); origin = basis.xform(-origin); } -Transform Transform::inverse() const { +Transform3D Transform3D::inverse() const { // FIXME: this function assumes the basis is a rotation matrix, with no scaling. - // Transform::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. - Transform ret = *this; + // Transform3D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. + Transform3D ret = *this; ret.invert(); return ret; } -void Transform::rotate(const Vector3 &p_axis, real_t p_phi) { +void Transform3D::rotate(const Vector3 &p_axis, real_t p_phi) { *this = rotated(p_axis, p_phi); } -Transform Transform::rotated(const Vector3 &p_axis, real_t p_phi) const { - return Transform(Basis(p_axis, p_phi), Vector3()) * (*this); +Transform3D Transform3D::rotated(const Vector3 &p_axis, real_t p_phi) const { + return Transform3D(Basis(p_axis, p_phi), Vector3()) * (*this); } -void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) { +void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_phi) { basis.rotate(p_axis, p_phi); } -Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { - Transform t = *this; +Transform3D Transform3D::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { + Transform3D t = *this; t.set_look_at(origin, p_target, p_up); return t; } -void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { +void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { #ifdef MATH_CHECKS ERR_FAIL_COND(p_eye == p_target); ERR_FAIL_COND(p_up.length() == 0); @@ -108,105 +108,105 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const origin = p_eye; } -Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) const { +Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ Vector3 src_scale = basis.get_scale(); - Quat src_rot = basis.get_rotation_quat(); + Quaternion src_rot = basis.get_rotation_quaternion(); Vector3 src_loc = origin; Vector3 dst_scale = p_transform.basis.get_scale(); - Quat dst_rot = p_transform.basis.get_rotation_quat(); + Quaternion dst_rot = p_transform.basis.get_rotation_quaternion(); Vector3 dst_loc = p_transform.origin; - Transform interp; - interp.basis.set_quat_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c)); + Transform3D interp; + interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c)); interp.origin = src_loc.lerp(dst_loc, p_c); return interp; } -void Transform::scale(const Vector3 &p_scale) { +void Transform3D::scale(const Vector3 &p_scale) { basis.scale(p_scale); origin *= p_scale; } -Transform Transform::scaled(const Vector3 &p_scale) const { - Transform t = *this; +Transform3D Transform3D::scaled(const Vector3 &p_scale) const { + Transform3D t = *this; t.scale(p_scale); return t; } -void Transform::scale_basis(const Vector3 &p_scale) { +void Transform3D::scale_basis(const Vector3 &p_scale) { basis.scale(p_scale); } -void Transform::translate(real_t p_tx, real_t p_ty, real_t p_tz) { +void Transform3D::translate(real_t p_tx, real_t p_ty, real_t p_tz) { translate(Vector3(p_tx, p_ty, p_tz)); } -void Transform::translate(const Vector3 &p_translation) { +void Transform3D::translate(const Vector3 &p_translation) { for (int i = 0; i < 3; i++) { origin[i] += basis[i].dot(p_translation); } } -Transform Transform::translated(const Vector3 &p_translation) const { - Transform t = *this; +Transform3D Transform3D::translated(const Vector3 &p_translation) const { + Transform3D t = *this; t.translate(p_translation); return t; } -void Transform::orthonormalize() { +void Transform3D::orthonormalize() { basis.orthonormalize(); } -Transform Transform::orthonormalized() const { - Transform _copy = *this; +Transform3D Transform3D::orthonormalized() const { + Transform3D _copy = *this; _copy.orthonormalize(); return _copy; } -bool Transform::is_equal_approx(const Transform &p_transform) const { +bool Transform3D::is_equal_approx(const Transform3D &p_transform) const { return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin); } -bool Transform::operator==(const Transform &p_transform) const { +bool Transform3D::operator==(const Transform3D &p_transform) const { return (basis == p_transform.basis && origin == p_transform.origin); } -bool Transform::operator!=(const Transform &p_transform) const { +bool Transform3D::operator!=(const Transform3D &p_transform) const { return (basis != p_transform.basis || origin != p_transform.origin); } -void Transform::operator*=(const Transform &p_transform) { +void Transform3D::operator*=(const Transform3D &p_transform) { origin = xform(p_transform.origin); basis *= p_transform.basis; } -Transform Transform::operator*(const Transform &p_transform) const { - Transform t = *this; +Transform3D Transform3D::operator*(const Transform3D &p_transform) const { + Transform3D t = *this; t *= p_transform; return t; } -Transform::operator String() const { +Transform3D::operator String() const { return basis.operator String() + " - " + origin.operator String(); } -Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) : +Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) : basis(p_basis), origin(p_origin) { } -Transform::Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : +Transform3D::Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : origin(p_origin) { basis.set_axis(0, p_x); basis.set_axis(1, p_y); basis.set_axis(2, p_z); } -Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) { +Transform3D::Transform3D(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) { basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz); origin = Vector3(ox, oy, oz); } diff --git a/core/math/transform.h b/core/math/transform_3d.h index 1c05dbe554..078a2ca11a 100644 --- a/core/math/transform.h +++ b/core/math/transform_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* transform.h */ +/* transform_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -35,31 +35,31 @@ #include "core/math/basis.h" #include "core/math/plane.h" -class Transform { +class Transform3D { public: Basis basis; Vector3 origin; void invert(); - Transform inverse() const; + Transform3D inverse() const; void affine_invert(); - Transform affine_inverse() const; + Transform3D affine_inverse() const; - Transform rotated(const Vector3 &p_axis, real_t p_phi) const; + Transform3D rotated(const Vector3 &p_axis, real_t p_phi) const; void rotate(const Vector3 &p_axis, real_t p_phi); void rotate_basis(const Vector3 &p_axis, real_t p_phi); void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); - Transform looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)) const; + Transform3D looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)) const; void scale(const Vector3 &p_scale); - Transform scaled(const Vector3 &p_scale) const; + Transform3D scaled(const Vector3 &p_scale) const; void scale_basis(const Vector3 &p_scale); void translate(real_t p_tx, real_t p_ty, real_t p_tz); void translate(const Vector3 &p_translation); - Transform translated(const Vector3 &p_translation) const; + Transform3D translated(const Vector3 &p_translation) const; const Basis &get_basis() const { return basis; } void set_basis(const Basis &p_basis) { basis = p_basis; } @@ -68,11 +68,11 @@ public: void set_origin(const Vector3 &p_origin) { origin = p_origin; } void orthonormalize(); - Transform orthonormalized() const; - bool is_equal_approx(const Transform &p_transform) const; + Transform3D orthonormalized() const; + bool is_equal_approx(const Transform3D &p_transform) const; - bool operator==(const Transform &p_transform) const; - bool operator!=(const Transform &p_transform) const; + bool operator==(const Transform3D &p_transform) const; + bool operator!=(const Transform3D &p_transform) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const; @@ -86,14 +86,14 @@ public: _FORCE_INLINE_ Vector<Vector3> xform(const Vector<Vector3> &p_array) const; _FORCE_INLINE_ Vector<Vector3> xform_inv(const Vector<Vector3> &p_array) const; - void operator*=(const Transform &p_transform); - Transform operator*(const Transform &p_transform) const; + void operator*=(const Transform3D &p_transform); + Transform3D operator*(const Transform3D &p_transform) const; - Transform interpolate_with(const Transform &p_transform, real_t p_c) const; + Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; - _FORCE_INLINE_ Transform inverse_xform(const Transform &t) const { + _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const { Vector3 v = t.origin - origin; - return Transform(basis.transpose_xform(t.basis), + return Transform3D(basis.transpose_xform(t.basis), basis.xform(v)); } @@ -106,20 +106,20 @@ public: operator String() const; - Transform() {} - Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3()); - Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin); - Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz); + Transform3D() {} + Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3()); + Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin); + Transform3D(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz); }; -_FORCE_INLINE_ Vector3 Transform::xform(const Vector3 &p_vector) const { +_FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const { return Vector3( basis[0].dot(p_vector) + origin.x, basis[1].dot(p_vector) + origin.y, basis[2].dot(p_vector) + origin.z); } -_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3 &p_vector) const { +_FORCE_INLINE_ Vector3 Transform3D::xform_inv(const Vector3 &p_vector) const { Vector3 v = p_vector - origin; return Vector3( @@ -128,7 +128,7 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3 &p_vector) const { (basis.elements[0][2] * v.x) + (basis.elements[1][2] * v.y) + (basis.elements[2][2] * v.z)); } -_FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const { +_FORCE_INLINE_ Plane Transform3D::xform(const Plane &p_plane) const { Vector3 point = p_plane.normal * p_plane.d; Vector3 point_dir = point + p_plane.normal; point = xform(point); @@ -141,7 +141,7 @@ _FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const { return Plane(normal, d); } -_FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const { +_FORCE_INLINE_ Plane Transform3D::xform_inv(const Plane &p_plane) const { Vector3 point = p_plane.normal * p_plane.d; Vector3 point_dir = point + p_plane.normal; point = xform_inv(point); @@ -154,7 +154,7 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const { return Plane(normal, d); } -_FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const { +_FORCE_INLINE_ AABB Transform3D::xform(const AABB &p_aabb) const { /* http://dev.theomader.com/transform-bounding-boxes/ */ Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; @@ -179,7 +179,7 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const { return r_aabb; } -_FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const { +_FORCE_INLINE_ AABB Transform3D::xform_inv(const AABB &p_aabb) const { /* define vertices */ Vector3 vertices[8] = { Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), @@ -203,7 +203,7 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const { return ret; } -Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const { +Vector<Vector3> Transform3D::xform(const Vector<Vector3> &p_array) const { Vector<Vector3> array; array.resize(p_array.size()); @@ -216,7 +216,7 @@ Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const { return array; } -Vector<Vector3> Transform::xform_inv(const Vector<Vector3> &p_array) const { +Vector<Vector3> Transform3D::xform_inv(const Vector<Vector3> &p_array) const { Vector<Vector3> array; array.resize(p_array.size()); diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 23c0c686a2..903d5951a8 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -600,7 +600,7 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *vertexptr = vertices.ptr(); const BVH *bvhptr = bvh.ptr(); - Transform scale(Basis().scaled(p_scale)); + Transform3D scale(Basis().scaled(p_scale)); int pos = bvh.size() - 1; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 46a08b53ab..ea430b15c4 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -122,14 +122,20 @@ Vector2 Vector2::project(const Vector2 &p_to) const { return p_to * (dot(p_to) / p_to.length_squared()); } +Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const { + return Vector2( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y)); +} + Vector2 Vector2::snapped(const Vector2 &p_step) const { return Vector2( Math::snapped(x, p_step.x), Math::snapped(y, p_step.y)); } -Vector2 Vector2::clamped(real_t p_len) const { - real_t l = length(); +Vector2 Vector2::limit_length(const real_t p_len) const { + const real_t l = length(); Vector2 v = *this; if (l > 0 && p_len < l) { v /= l; @@ -189,6 +195,12 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { /* Vector2i */ +Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const { + return Vector2i( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y)); +} + Vector2i Vector2i::operator+(const Vector2i &p_v) const { return Vector2i(x + p_v.x, y + p_v.y); } diff --git a/core/math/vector2.h b/core/math/vector2.h index 6abe0f5ea9..b0d2049f55 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -84,6 +84,7 @@ struct Vector2 { real_t length() const; real_t length_squared() const; + Vector2 limit_length(const real_t p_len = 1.0) const; Vector2 min(const Vector2 &p_vector2) const { return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y)); @@ -107,8 +108,6 @@ struct Vector2 { Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; - Vector2 clamped(real_t p_len) const; - _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, real_t p_weight) const; _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, real_t p_weight) const; Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const; @@ -163,6 +162,7 @@ struct Vector2 { Vector2 ceil() const; Vector2 round() const; Vector2 snapped(const Vector2 &p_by) const; + Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const; real_t aspect() const { return width / height; } operator String() const { return String::num(x) + ", " + String::num(y); } @@ -338,6 +338,7 @@ struct Vector2i { real_t aspect() const { return width / (real_t)height; } Vector2i sign() const { return Vector2i(SGN(x), SGN(y)); } Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); } + Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const; operator String() const { return String::num(x) + ", " + String::num(y); } diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index d4317d506c..d5ca985244 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -52,6 +52,13 @@ real_t Vector3::get_axis(int p_axis) const { return operator[](p_axis); } +Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { + return Vector3( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z)); +} + void Vector3::snap(Vector3 p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); @@ -64,6 +71,17 @@ Vector3 Vector3::snapped(Vector3 p_step) const { return v; } +Vector3 Vector3::limit_length(const real_t p_len) const { + const real_t l = length(); + Vector3 v = *this; + if (l > 0 && p_len < l) { + v /= l; + v *= p_len; + } + + return v; +} + Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const { Vector3 p0 = p_pre_a; Vector3 p1 = *this; diff --git a/core/math/vector3.h b/core/math/vector3.h index adfc52566f..d8d3cd3cc0 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -86,6 +86,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 normalized() const; _FORCE_INLINE_ bool is_normalized() const; _FORCE_INLINE_ Vector3 inverse() const; + Vector3 limit_length(const real_t p_len = 1.0) const; _FORCE_INLINE_ void zero(); @@ -112,6 +113,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 sign() const; _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ Vector3 round() const; + Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const; _FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const; diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp index 167fa3221d..a82db7f7fc 100644 --- a/core/math/vector3i.cpp +++ b/core/math/vector3i.cpp @@ -48,6 +48,13 @@ int Vector3i::max_axis() const { return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); } +Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const { + return Vector3i( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z)); +} + Vector3i::operator String() const { return (itos(x) + ", " + itos(y) + ", " + itos(z)); } diff --git a/core/math/vector3i.h b/core/math/vector3i.h index b0411fb62e..37c7c1c368 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -69,6 +69,7 @@ struct Vector3i { _FORCE_INLINE_ Vector3i abs() const; _FORCE_INLINE_ Vector3i sign() const; + Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const; /* Operators */ diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index fb7eb42738..5bf874ccae 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -501,12 +501,27 @@ void ClassDB::add_compatibility_class(const StringName &p_class, const StringNam compat_classes[p_class] = p_fallback; } +thread_local bool initializing_with_extension = false; +thread_local ObjectNativeExtension *initializing_extension = nullptr; +thread_local void *initializing_extension_instance = nullptr; + +void ClassDB::instance_get_native_extension_data(ObjectNativeExtension **r_extension, void **r_extension_instance) { + if (initializing_with_extension) { + *r_extension = initializing_extension; + *r_extension_instance = initializing_extension_instance; + initializing_with_extension = false; + } else { + *r_extension = nullptr; + *r_extension_instance = nullptr; + } +} + Object *ClassDB::instance(const StringName &p_class) { ClassInfo *ti; { OBJTYPE_RLOCK; ti = classes.getptr(p_class); - if (!ti || ti->disabled || !ti->creation_func) { + if (!ti || ti->disabled || !ti->creation_func || (ti->native_extension && !ti->native_extension->create_instance)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } @@ -521,6 +536,11 @@ Object *ClassDB::instance(const StringName &p_class) { return nullptr; } #endif + if (ti->native_extension) { + initializing_with_extension = true; + initializing_extension = ti->native_extension; + initializing_extension_instance = ti->native_extension->create_instance(ti->native_extension->create_instance_userdata); + } return ti->creation_func(); } @@ -534,7 +554,7 @@ bool ClassDB::can_instance(const StringName &p_class) { return false; } #endif - return (!ti->disabled && ti->creation_func != nullptr); + return (!ti->disabled && ti->creation_func != nullptr && !(ti->native_extension && !ti->native_extension->create_instance)); } void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { @@ -1310,6 +1330,24 @@ bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inhe return false; } +void ClassDB::bind_method_custom(const StringName &p_class, MethodBind *p_method) { + ClassInfo *type = classes.getptr(p_class); + if (!type) { + ERR_FAIL_MSG("Couldn't bind custom method '" + p_method->get_name() + "' for instance '" + p_class + "'."); + } + + if (type->method_map.has(p_method->get_name())) { + // overloading not supported + ERR_FAIL_MSG("Method already bound '" + p_class + "::" + p_method->get_name() + "'."); + } + +#ifdef DEBUG_METHODS_ENABLED + type->method_order.push_back(p_method->get_name()); +#endif + + type->method_map[p_method->get_name()] = p_method; +} + #ifdef DEBUG_METHODS_ENABLED MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) { StringName mdname = method_name.name; @@ -1545,6 +1583,26 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con return var; } +void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { + GLOBAL_LOCK_FUNCTION; + + ERR_FAIL_COND_MSG(classes.has(p_extension->class_name), "Class already registered: " + String(p_extension->class_name)); + ERR_FAIL_COND_MSG(classes.has(p_extension->parent_class_name), "Parent class name for extension class not found: " + String(p_extension->parent_class_name)); + + ClassInfo *parent = classes.getptr(p_extension->parent_class_name); + + ClassInfo c; + c.api = p_extension->editor_class ? API_EDITOR_EXTENSION : API_EXTENSION; + c.native_extension = p_extension; + c.name = p_extension->class_name; + c.creation_func = parent->creation_func; + c.inherits = parent->name; + c.class_ptr = parent->class_ptr; + c.inherits_ptr = parent; + + classes[p_extension->class_name] = c; +} + RWLock ClassDB::lock; void ClassDB::cleanup_defaults() { diff --git a/core/object/class_db.h b/core/object/class_db.h index 6fd5748dbb..4355c9b0ea 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -97,6 +97,8 @@ public: enum APIType { API_CORE, API_EDITOR, + API_EXTENSION, + API_EDITOR_EXTENSION, API_NONE }; @@ -115,6 +117,8 @@ public: ClassInfo *inherits_ptr = nullptr; void *class_ptr = nullptr; + ObjectNativeExtension *native_extension = nullptr; + HashMap<StringName, MethodBind *> method_map; HashMap<StringName, int> constant_map; HashMap<StringName, List<StringName>> enum_map; @@ -199,6 +203,8 @@ public: //nothing } + static void register_extension_class(ObjectNativeExtension *p_extension); + template <class T> static Object *_create_ptr_func() { return T::create(); @@ -226,6 +232,7 @@ public: static bool is_parent_class(const StringName &p_class, const StringName &p_inherits); static bool can_instance(const StringName &p_class); static Object *instance(const StringName &p_class); + static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, void **r_extension_instance); static APIType get_api_type(const StringName &p_class); static uint64_t get_api_hash(APIType p_api); @@ -334,6 +341,8 @@ public: return bind; } + static void bind_method_custom(const StringName &p_class, MethodBind *p_method); + static void add_signal(StringName p_class, const MethodInfo &p_signal); static bool has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance = false); static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal); diff --git a/core/object/object.cpp b/core/object/object.cpp index a8b2c4a939..7e1c3855c0 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -385,6 +385,15 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid } } + if (_extension && _extension->set) { + if (_extension->set(_extension_instance, &p_name, &p_value)) { + if (r_valid) { + *r_valid = true; + } + return; + } + } + //try built-in setgetter { if (ClassDB::set_property(this, p_name, p_value, r_valid)) { @@ -451,6 +460,15 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { } } + if (_extension && _extension->get) { + if (_extension->get(_extension_instance, &p_name, &ret)) { + if (r_valid) { + *r_valid = true; + } + return ret; + } + } + //try built-in setgetter { if (ClassDB::get_property(const_cast<Object *>(this), p_name, ret)) { @@ -596,6 +614,17 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons _get_property_listv(p_list, p_reversed); + if (_extension && _extension->get_property_list) { + uint32_t pcount; + const ObjectNativeExtension::PInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount); + for (uint32_t i = 0; i < pcount; i++) { + p_list->push_back(PropertyInfo(Variant::Type(pinfo[i].type), pinfo[i].class_name, PropertyHint(pinfo[i].hint), pinfo[i].hint_string, pinfo[i].usage, pinfo[i].class_name)); + } + if (_extension->free_property_list) { + _extension->free_property_list(_extension_instance, pinfo); + } + } + if (!is_class("Script")) { // can still be set, but this is for user-friendliness p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT)); } @@ -761,6 +790,7 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a Variant ret; OBJ_DEBUG_LOCK + if (script_instance) { ret = script_instance->call(p_method, p_args, p_argcount, r_error); //force jumptable @@ -778,6 +808,8 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a } } + //extension does not need this, because all methods are registered in MethodBind + MethodBind *method = ClassDB::get_method(get_class_name(), p_method); if (method) { @@ -795,6 +827,10 @@ void Object::notification(int p_notification, bool p_reversed) { if (script_instance) { script_instance->notification(p_notification); } + + if (_extension && _extension->notification) { + _extension->notification(_extension_instance, p_notification); + } } String Object::to_string() { @@ -805,6 +841,9 @@ String Object::to_string() { return ret; } } + if (_extension && _extension->to_string) { + return _extension->to_string(_extension_instance); + } return "[" + get_class() + ":" + itos(get_instance_id()) + "]"; } @@ -1751,6 +1790,8 @@ void Object::_construct_object(bool p_reference) { _instance_id = ObjectDB::add_instance(this); memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS); + ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance); + #ifdef DEBUG_ENABLED _lock_index.init(1); #endif @@ -1770,6 +1811,12 @@ Object::~Object() { } script_instance = nullptr; + if (_extension && _extension->free_instance) { + _extension->free_instance(_extension->create_instance_userdata, _extension_instance); + _extension = nullptr; + _extension_instance = nullptr; + } + const StringName *S = nullptr; if (_emitting) { diff --git a/core/object/object.h b/core/object/object.h index 448a33d3bc..137025f323 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -238,6 +238,50 @@ struct MethodInfo { ////else //return nullptr; +// API used to extend in GDNative and other C compatible compiled languages +class MethodBind; + +struct ObjectNativeExtension { + ObjectNativeExtension *parent = nullptr; + StringName parent_class_name; + StringName class_name; + bool editor_class = false; + bool (*set)(void *instance, const void *name, const void *value) = nullptr; + bool (*get)(void *instance, const void *name, void *ret_variant) = nullptr; + struct PInfo { + uint32_t type; + const char *name; + const char *class_name; + uint32_t hint; + const char *hint_string; + uint32_t usage; + }; + const PInfo *(*get_property_list)(void *instance, uint32_t *count) = nullptr; + void (*free_property_list)(void *instance, const PInfo *) = nullptr; + + //call is not used, as all methods registered in ClassDB + + void (*notification)(void *instance, int32_t what) = nullptr; + const char *(*to_string)(void *instance) = nullptr; + + void (*reference)(void *instance) = nullptr; + void (*unreference)(void *instance) = nullptr; + + _FORCE_INLINE_ bool is_class(const String &p_class) const { + const ObjectNativeExtension *e = this; + while (e) { + if (p_class == e->class_name.operator String()) { + return true; + } + e = e->parent; + } + return false; + } + void *create_instance_userdata = nullptr; + void *(*create_instance)(void *create_instance_userdata) = nullptr; + void (*free_instance)(void *create_instance_userdata, void *instance) = nullptr; +}; + /* the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. */ @@ -262,9 +306,15 @@ private: \ public: \ virtual String get_class() const override { \ + if (_get_extension()) { \ + return _get_extension()->class_name.operator String(); \ + } \ return String(#m_class); \ } \ virtual const StringName *_get_class_namev() const override { \ + if (_get_extension()) { \ + return &_get_extension()->class_name; \ + } \ if (!_class_name) { \ _class_name = get_class_static(); \ } \ @@ -297,7 +347,12 @@ public: static String inherits_static() { \ return String(#m_inherits); \ } \ - virtual bool is_class(const String &p_class) const override { return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); } \ + virtual bool is_class(const String &p_class) const override { \ + if (_get_extension() && _get_extension()->is_class(p_class)) { \ + return true; \ + } \ + return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \ + } \ virtual bool is_class_ptr(void *p_ptr) const override { return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); } \ \ static void get_valid_parents_static(List<String> *p_parents) { \ @@ -440,6 +495,9 @@ private: friend bool predelete_handler(Object *); friend void postinitialize_handler(Object *); + ObjectNativeExtension *_extension = nullptr; + void *_extension_instance = nullptr; + struct SignalData { struct Slot { int reference_count = 0; @@ -495,6 +553,8 @@ private: Object(bool p_reference); protected: + _ALWAYS_INLINE_ const ObjectNativeExtension *_get_extension() const { return _extension; } + _ALWAYS_INLINE_ void *_get_extension_instance() const { return _extension_instance; } virtual void _initialize_classv() { initialize_class(); } virtual bool _setv(const StringName &p_name, const Variant &p_property) { return false; }; virtual bool _getv(const StringName &p_name, Variant &r_property) const { return false; }; @@ -610,13 +670,25 @@ public: static String get_parent_class_static() { return String(); } static String get_category_static() { return String(); } - virtual String get_class() const { return "Object"; } + virtual String get_class() const { + if (_extension) + return _extension->class_name.operator String(); + return "Object"; + } virtual String get_save_class() const { return get_class(); } //class stored when saving - virtual bool is_class(const String &p_class) const { return (p_class == "Object"); } + virtual bool is_class(const String &p_class) const { + if (_extension && _extension->is_class(p_class)) { + return true; + } + return (p_class == "Object"); + } virtual bool is_class_ptr(void *p_ptr) const { return get_class_ptr_static() == p_ptr; } _FORCE_INLINE_ const StringName &get_class_name() const { + if (_extension) { + return _extension->class_name; + } if (!_class_ptr) { return *_get_class_namev(); } else { diff --git a/core/object/reference.cpp b/core/object/reference.cpp index 22e4e8a336..086b761e95 100644 --- a/core/object/reference.cpp +++ b/core/object/reference.cpp @@ -62,6 +62,9 @@ bool Reference::reference() { if (get_script_instance()) { get_script_instance()->refcount_incremented(); } + if (_get_extension() && _get_extension()->reference) { + _get_extension()->reference(_get_extension_instance()); + } if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { @@ -83,6 +86,9 @@ bool Reference::unreference() { bool script_ret = get_script_instance()->refcount_decremented(); die = die && script_ret; } + if (_get_extension() && _get_extension()->unreference) { + _get_extension()->unreference(_get_extension_instance()); + } if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 42fb0a0caf..aa91c6cbf7 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -585,14 +585,6 @@ Variant PlaceHolderScriptInstance::property_get_fallback(const StringName &p_nam return Variant(); } -uint16_t PlaceHolderScriptInstance::get_rpc_method_id(const StringName &p_method) const { - return UINT16_MAX; -} - -uint16_t PlaceHolderScriptInstance::get_rset_property_id(const StringName &p_method) const { - return UINT16_MAX; -} - PlaceHolderScriptInstance::PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner) : owner(p_owner), language(p_language), diff --git a/core/object/script_language.h b/core/object/script_language.h index 9ed3c7e80f..a22e91870e 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -41,21 +41,6 @@ class ScriptLanguage; typedef void (*ScriptEditRequestFunction)(const String &p_path); -struct ScriptNetData { - StringName name; - MultiplayerAPI::RPCMode mode; - bool operator==(ScriptNetData const &p_other) const { - return name == p_other.name; - } -}; - -struct SortNetData { - StringName::AlphCompare compare; - bool operator()(const ScriptNetData &p_a, const ScriptNetData &p_b) const { - return compare(p_a.name, p_b.name); - } -}; - class ScriptServer { enum { MAX_LANGUAGES = 16 @@ -174,17 +159,7 @@ public: virtual bool is_placeholder_fallback_enabled() const { return false; } - virtual Vector<ScriptNetData> get_rpc_methods() const = 0; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const = 0; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0; - - virtual Vector<ScriptNetData> get_rset_properties() const = 0; - virtual uint16_t get_rset_property_id(const StringName &p_property) const = 0; - virtual StringName get_rset_property(const uint16_t p_rset_property_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const = 0; Script() {} }; @@ -225,17 +200,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid); virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid); - virtual Vector<ScriptNetData> get_rpc_methods() const = 0; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const = 0; - virtual StringName get_rpc_method(uint16_t p_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0; - - virtual Vector<ScriptNetData> get_rset_properties() const = 0; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const = 0; - virtual StringName get_rset_property(uint16_t p_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const = 0; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const = 0; virtual ScriptLanguage *get_language() = 0; virtual ~ScriptInstance(); @@ -447,17 +412,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr); virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = nullptr); - virtual Vector<ScriptNetData> get_rpc_methods() const { return Vector<ScriptNetData>(); } - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(uint16_t p_id) const { return StringName(); } - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const { return MultiplayerAPI::RPC_MODE_DISABLED; } - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const { return MultiplayerAPI::RPC_MODE_DISABLED; } - - virtual Vector<ScriptNetData> get_rset_properties() const { return Vector<ScriptNetData>(); } - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(uint16_t p_id) const { return StringName(); } - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const { return MultiplayerAPI::RPC_MODE_DISABLED; } - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const { return MultiplayerAPI::RPC_MODE_DISABLED; } + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const { return Vector<MultiplayerAPI::RPCConfig>(); } PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner); ~PlaceHolderScriptInstance(); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index d1b940190a..d21c0bd9a2 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -164,7 +164,7 @@ uint16_t FileAccess::get_16() const { a = get_8(); b = get_8(); - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -182,7 +182,7 @@ uint32_t FileAccess::get_32() const { a = get_16(); b = get_16(); - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -200,7 +200,7 @@ uint64_t FileAccess::get_64() const { a = get_32(); b = get_32(); - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -401,7 +401,7 @@ void FileAccess::store_16(uint16_t p_dest) { a = p_dest & 0xFF; b = p_dest >> 8; - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -415,7 +415,7 @@ void FileAccess::store_32(uint32_t p_dest) { a = p_dest & 0xFFFF; b = p_dest >> 16; - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -429,7 +429,7 @@ void FileAccess::store_64(uint64_t p_dest) { a = p_dest & 0xFFFFFFFF; b = p_dest >> 32; - if (endian_swap) { + if (big_endian) { SWAP(a, b); } @@ -551,6 +551,7 @@ void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_ } void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) { + ERR_FAIL_COND(!p_src && p_length > 0); for (uint64_t i = 0; i < p_length; i++) { store_8(p_src[i]); } diff --git a/core/os/file_access.h b/core/os/file_access.h index 1b9fb2f422..5804aa2c47 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -52,7 +52,7 @@ public: typedef void (*FileCloseFailNotify)(const String &); typedef FileAccess *(*CreateFunc)(); - bool endian_swap = false; + bool big_endian = false; bool real_is_double = false; virtual uint32_t _get_unix_permissions(const String &p_file) = 0; @@ -115,13 +115,13 @@ public: virtual Vector<String> get_csv_line(const String &p_delim = ",") const; virtual String get_as_utf8_string() const; - /**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) + /** + * Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) * It's not about the current CPU type but file formats. - * this flags get reset to false (little endian) on each open + * This flag gets reset to `false` (little endian) on each open. */ - - virtual void set_endian_swap(bool p_swap) { endian_swap = p_swap; } - inline bool get_endian_swap() const { return endian_swap; } + virtual void set_big_endian(bool p_big_endian) { big_endian = p_big_endian; } + inline bool is_big_endian() const { return big_endian; } virtual Error get_error() const = 0; ///< get last error diff --git a/core/templates/command_queue_mt.cpp b/core/templates/command_queue_mt.cpp index 238bf3975c..04a8095f0b 100644 --- a/core/templates/command_queue_mt.cpp +++ b/core/templates/command_queue_mt.cpp @@ -70,35 +70,7 @@ CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() { return &sync_sems[idx]; } -bool CommandQueueMT::dealloc_one() { -tryagain: - if (dealloc_ptr == (write_ptr_and_epoch >> 1)) { - // The queue is empty - return false; - } - - uint32_t size = *(uint32_t *)&command_mem[dealloc_ptr]; - - if (size == 0) { - // End of command buffer wrap down - dealloc_ptr = 0; - goto tryagain; - } - - if (size & 1) { - // Still used, nothing can be deallocated - return false; - } - - dealloc_ptr += (size >> 1) + 8; - return true; -} - CommandQueueMT::CommandQueueMT(bool p_sync) { - command_mem_size = GLOBAL_DEF_RST("memory/limits/command_queue/multithreading_queue_size_kb", DEFAULT_COMMAND_MEM_SIZE_KB); - ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/command_queue/multithreading_queue_size_kb", PropertyInfo(Variant::INT, "memory/limits/command_queue/multithreading_queue_size_kb", PROPERTY_HINT_RANGE, "1,4096,1,or_greater")); - command_mem_size *= 1024; - command_mem = (uint8_t *)memalloc(command_mem_size); if (p_sync) { sync = memnew(Semaphore); } @@ -108,5 +80,4 @@ CommandQueueMT::~CommandQueueMT() { if (sync) { memdelete(sync); } - memfree(command_mem); } diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h index 0012cea72d..acc46da0d5 100644 --- a/core/templates/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -34,6 +34,8 @@ #include "core/os/memory.h" #include "core/os/mutex.h" #include "core/os/semaphore.h" +#include "core/string/print_string.h" +#include "core/templates/local_vector.h" #include "core/templates/simple_type.h" #include "core/typedefs.h" @@ -334,11 +336,7 @@ class CommandQueueMT { SYNC_SEMAPHORES = 8 }; - uint8_t *command_mem = nullptr; - uint32_t read_ptr_and_epoch = 0; - uint32_t write_ptr_and_epoch = 0; - uint32_t dealloc_ptr = 0; - uint32_t command_mem_size = 0; + LocalVector<uint8_t> command_mem; SyncSemaphore sync_sems[SYNC_SEMAPHORES]; Mutex mutex; Semaphore *sync = nullptr; @@ -346,138 +344,47 @@ class CommandQueueMT { template <class T> T *allocate() { // alloc size is size+T+safeguard - uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8; - - // Assert that the buffer is big enough to hold at least two messages. - ERR_FAIL_COND_V(alloc_size * 2 + sizeof(uint32_t) > command_mem_size, nullptr); - - tryagain: - uint32_t write_ptr = write_ptr_and_epoch >> 1; - - if (write_ptr < dealloc_ptr) { - // behind dealloc_ptr, check that there is room - if ((dealloc_ptr - write_ptr) <= alloc_size) { - // There is no more room, try to deallocate something - if (dealloc_one()) { - goto tryagain; - } - return nullptr; - } - } else { - // ahead of dealloc_ptr, check that there is room - - if ((command_mem_size - write_ptr) < alloc_size + sizeof(uint32_t)) { - // no room at the end, wrap down; - - if (dealloc_ptr == 0) { // don't want write_ptr to become dealloc_ptr - - // There is no more room, try to deallocate something - if (dealloc_one()) { - goto tryagain; - } - return nullptr; - } - - // if this happens, it's a bug - ERR_FAIL_COND_V((command_mem_size - write_ptr) < 8, nullptr); - // zero means, wrap to beginning - - uint32_t *p = (uint32_t *)&command_mem[write_ptr]; - *p = 1; - write_ptr_and_epoch = 0 | (1 & ~write_ptr_and_epoch); // Invert epoch. - // See if we can get the thread to run and clear up some more space while we wait. - // This is required if alloc_size * 2 + 4 > COMMAND_MEM_SIZE - if (sync) { - sync->post(); - } - goto tryagain; - } - } - // Allocate the size and the 'in use' bit. - // First bit used to mark if command is still in use (1) - // or if it has been destroyed and can be deallocated (0). - uint32_t size = (sizeof(T) + 8 - 1) & ~(8 - 1); - uint32_t *p = (uint32_t *)&command_mem[write_ptr]; - *p = (size << 1) | 1; - write_ptr += 8; - // allocate the command - T *cmd = memnew_placement(&command_mem[write_ptr], T); - write_ptr += size; - write_ptr_and_epoch = (write_ptr << 1) | (write_ptr_and_epoch & 1); + uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)); + uint64_t size = command_mem.size(); + command_mem.resize(size + alloc_size + 8); + *(uint64_t *)&command_mem[size] = alloc_size; + T *cmd = memnew_placement(&command_mem[size + 8], T); return cmd; } template <class T> T *allocate_and_lock() { lock(); - T *ret; - - while ((ret = allocate<T>()) == nullptr) { - unlock(); - // sleep a little until fetch happened and some room is made - wait_for_flush(); - lock(); - } - + T *ret = allocate<T>(); return ret; } - bool flush_one(bool p_lock = true) { - if (p_lock) { - lock(); - } - tryagain: - - // tried to read an empty queue - if (read_ptr_and_epoch == write_ptr_and_epoch) { - if (p_lock) { - unlock(); - } - return false; - } - - uint32_t read_ptr = read_ptr_and_epoch >> 1; - uint32_t size_ptr = read_ptr; - uint32_t size = *(uint32_t *)&command_mem[read_ptr] >> 1; - - if (size == 0) { - *(uint32_t *)&command_mem[read_ptr] = 0; // clear in-use bit. - //end of ringbuffer, wrap - read_ptr_and_epoch = 0 | (1 & ~read_ptr_and_epoch); // Invert epoch. - goto tryagain; - } - - read_ptr += 8; + void _flush() { + lock(); - CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]); + uint64_t read_ptr = 0; + uint64_t limit = command_mem.size(); - read_ptr += size; + while (read_ptr < limit) { + uint64_t size = *(uint64_t *)&command_mem[read_ptr]; + read_ptr += 8; + CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]); - read_ptr_and_epoch = (read_ptr << 1) | (read_ptr_and_epoch & 1); + cmd->call(); //execute the function + cmd->post(); //release in case it needs sync/ret + cmd->~CommandBase(); //should be done, so erase the command - if (p_lock) { - unlock(); - } - cmd->call(); - if (p_lock) { - lock(); + read_ptr += size; } - cmd->post(); - cmd->~CommandBase(); - *(uint32_t *)&command_mem[size_ptr] &= ~1; - - if (p_lock) { - unlock(); - } - return true; + command_mem.clear(); + unlock(); } void lock(); void unlock(); void wait_for_flush(); SyncSemaphore *_alloc_sync_sem(); - bool dealloc_one(); public: /* NORMAL PUSH COMMANDS */ @@ -492,23 +399,19 @@ public: DECL_PUSH_AND_SYNC(0) SPACE_SEP_LIST(DECL_PUSH_AND_SYNC, 15) - void wait_and_flush_one() { - ERR_FAIL_COND(!sync); - sync->wait(); - flush_one(); - } - _FORCE_INLINE_ void flush_if_pending() { - if (unlikely(read_ptr_and_epoch != write_ptr_and_epoch)) { - flush_all(); + if (unlikely(command_mem.size() > 0)) { + _flush(); } } void flush_all() { - //ERR_FAIL_COND(sync); - lock(); - while (flush_one(false)) { - } - unlock(); + _flush(); + } + + void wait_and_flush() { + ERR_FAIL_COND(!sync); + sync->wait(); + _flush(); } CommandQueueMT(bool p_sync); diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index dc378aed69..1257b54449 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -291,7 +291,7 @@ public: } /** - * Same as get, except it can return nullptr when item was not found. + * Same as get, except it can return nullptr when item was not found. * This is mainly used for speed purposes. */ @@ -324,7 +324,7 @@ public: } /** - * Same as get, except it can return nullptr when item was not found. + * Same as get, except it can return nullptr when item was not found. * This version is custom, will take a hash and a custom key (that should support operator==() */ @@ -443,7 +443,7 @@ public: /** * Get the next key to p_key, and the first key if p_key is null. - * Returns a pointer to the next key if found, nullptr otherwise. + * Returns a pointer to the next key if found, nullptr otherwise. * Adding/Removing elements while iterating will, of course, have unexpected results, don't do it. * * Example: diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h index 2c7c64cd78..025cc30db4 100644 --- a/core/templates/oa_hash_map.h +++ b/core/templates/oa_hash_map.h @@ -231,7 +231,7 @@ public: /** * returns true if the value was found, false otherwise. * - * if r_data is not nullptr then the value will be written to the object + * if r_data is not nullptr then the value will be written to the object * it points to. */ bool lookup(const TKey &p_key, TValue &r_data) const { @@ -249,7 +249,7 @@ public: /** * returns true if the value was found, false otherwise. * - * if r_data is not nullptr then the value will be written to the object + * if r_data is not nullptr then the value will be written to the object * it points to. */ TValue *lookup_ptr(const TKey &p_key) const { diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index e91029f330..d4ec5e570c 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -122,10 +122,10 @@ MAKE_PTRARG_BY_REFERENCE(Vector3); MAKE_PTRARG_BY_REFERENCE(Vector3i); MAKE_PTRARG(Transform2D); MAKE_PTRARG_BY_REFERENCE(Plane); -MAKE_PTRARG(Quat); +MAKE_PTRARG(Quaternion); MAKE_PTRARG_BY_REFERENCE(AABB); MAKE_PTRARG_BY_REFERENCE(Basis); -MAKE_PTRARG_BY_REFERENCE(Transform); +MAKE_PTRARG_BY_REFERENCE(Transform3D); MAKE_PTRARG_BY_REFERENCE(Color); MAKE_PTRARG(StringName); MAKE_PTRARG(NodePath); diff --git a/core/variant/type_info.h b/core/variant/type_info.h index d5b6d85dfb..76cb065d10 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -146,10 +146,10 @@ MAKE_TYPE_INFO(Rect2i, Variant::RECT2I) MAKE_TYPE_INFO(Vector3i, Variant::VECTOR3I) MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D) MAKE_TYPE_INFO(Plane, Variant::PLANE) -MAKE_TYPE_INFO(Quat, Variant::QUAT) +MAKE_TYPE_INFO(Quaternion, Variant::QUATERNION) MAKE_TYPE_INFO(AABB, Variant::AABB) MAKE_TYPE_INFO(Basis, Variant::BASIS) -MAKE_TYPE_INFO(Transform, Variant::TRANSFORM) +MAKE_TYPE_INFO(Transform3D, Variant::TRANSFORM3D) MAKE_TYPE_INFO(Color, Variant::COLOR) MAKE_TYPE_INFO(StringName, Variant::STRING_NAME) MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH) diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h index e0309aa3fe..900dcf7689 100644 --- a/core/variant/typed_array.h +++ b/core/variant/typed_array.h @@ -98,10 +98,10 @@ 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(Quaternion, Variant::QUATERNION) MAKE_TYPED_ARRAY(AABB, Variant::AABB) MAKE_TYPED_ARRAY(Basis, Variant::BASIS) -MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D) MAKE_TYPED_ARRAY(Color, Variant::COLOR) MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME) MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH) @@ -196,10 +196,10 @@ 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(Quaternion, Variant::QUATERNION) 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(Transform3D, Variant::TRANSFORM3D) MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR) MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME) MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH) diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 333dd8e8d1..2bde08742c 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -91,16 +91,16 @@ String Variant::get_type_name(Variant::Type p_type) { case AABB: { return "AABB"; } break; - case QUAT: { - return "Quat"; + case QUATERNION: { + return "Quaternion"; } break; case BASIS: { return "Basis"; } break; - case TRANSFORM: { - return "Transform"; + case TRANSFORM3D: { + return "Transform3D"; } break; @@ -275,7 +275,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { } break; case TRANSFORM2D: { static const Type valid[] = { - TRANSFORM, + TRANSFORM3D, NIL }; @@ -300,7 +300,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { } break; - case QUAT: { + case QUATERNION: { static const Type valid[] = { BASIS, NIL @@ -311,7 +311,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { } break; case BASIS: { static const Type valid[] = { - QUAT, + QUATERNION, VECTOR3, NIL }; @@ -319,10 +319,10 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { valid_types = valid; } break; - case TRANSFORM: { + case TRANSFORM3D: { static const Type valid[] = { TRANSFORM2D, - QUAT, + QUATERNION, BASIS, NIL }; @@ -582,7 +582,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } break; case TRANSFORM2D: { static const Type valid[] = { - TRANSFORM, + TRANSFORM3D, NIL }; @@ -607,7 +607,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } break; - case QUAT: { + case QUATERNION: { static const Type valid[] = { BASIS, NIL @@ -618,7 +618,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } break; case BASIS: { static const Type valid[] = { - QUAT, + QUATERNION, VECTOR3, NIL }; @@ -626,10 +626,10 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type valid_types = valid; } break; - case TRANSFORM: { + case TRANSFORM3D: { static const Type valid[] = { TRANSFORM2D, - QUAT, + QUATERNION, BASIS, NIL }; @@ -873,16 +873,16 @@ bool Variant::is_zero() const { case AABB: { return *_data._aabb == ::AABB(); } break; - case QUAT: { - return *reinterpret_cast<const Quat *>(_data._mem) == Quat(); + case QUATERNION: { + return *reinterpret_cast<const Quaternion *>(_data._mem) == Quaternion(); } break; case BASIS: { return *_data._basis == Basis(); } break; - case TRANSFORM: { - return *_data._transform == Transform(); + case TRANSFORM3D: { + return *_data._transform3d == Transform3D(); } break; @@ -1092,16 +1092,16 @@ void Variant::reference(const Variant &p_variant) { case AABB: { _data._aabb = memnew(::AABB(*p_variant._data._aabb)); } break; - case QUAT: { - memnew_placement(_data._mem, Quat(*reinterpret_cast<const Quat *>(p_variant._data._mem))); + case QUATERNION: { + memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem))); } break; case BASIS: { _data._basis = memnew(Basis(*p_variant._data._basis)); } break; - case TRANSFORM: { - _data._transform = memnew(Transform(*p_variant._data._transform)); + case TRANSFORM3D: { + _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d)); } break; // misc types @@ -1254,8 +1254,8 @@ void Variant::zero() { case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break; - case QUAT: - *reinterpret_cast<Quat *>(this->_data._mem) = Quat(); + case QUATERNION: + *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion(); break; case COLOR: *reinterpret_cast<Color *>(this->_data._mem) = Color(); @@ -1275,7 +1275,7 @@ void Variant::_clear_internal() { // no point, they don't allocate memory VECTOR3, PLANE, - QUAT, + QUATERNION, COLOR, VECTOR2, RECT2 @@ -1289,8 +1289,8 @@ void Variant::_clear_internal() { case BASIS: { memdelete(_data._basis); } break; - case TRANSFORM: { - memdelete(_data._transform); + case TRANSFORM3D: { + memdelete(_data._transform3d); } break; // misc types @@ -1653,11 +1653,10 @@ String Variant::stringify(List<const void *> &stack) const { return "(" + operator Vector3i() + ")"; case PLANE: return operator Plane(); - //case QUAT: case AABB: return operator ::AABB(); - case QUAT: - return "(" + operator Quat() + ")"; + case QUATERNION: + return "(" + operator Quaternion() + ")"; case BASIS: { Basis mat3 = operator Basis(); @@ -1682,8 +1681,8 @@ String Variant::stringify(List<const void *> &stack) const { return mtx + ")"; } break; - case TRANSFORM: - return operator Transform(); + case TRANSFORM3D: + return operator Transform3D(); case STRING_NAME: return operator StringName(); case NODE_PATH: @@ -1956,39 +1955,39 @@ Variant::operator ::AABB() const { Variant::operator Basis() const { if (type == BASIS) { return *_data._basis; - } else if (type == QUAT) { - return *reinterpret_cast<const Quat *>(_data._mem); + } else if (type == QUATERNION) { + return *reinterpret_cast<const Quaternion *>(_data._mem); } else if (type == VECTOR3) { return Basis(*reinterpret_cast<const Vector3 *>(_data._mem)); - } else if (type == TRANSFORM) { // unexposed in Variant::can_convert? - return _data._transform->basis; + } else if (type == TRANSFORM3D) { // unexposed in Variant::can_convert? + return _data._transform3d->basis; } else { return Basis(); } } -Variant::operator Quat() const { - if (type == QUAT) { - return *reinterpret_cast<const Quat *>(_data._mem); +Variant::operator Quaternion() const { + if (type == QUATERNION) { + return *reinterpret_cast<const Quaternion *>(_data._mem); } else if (type == BASIS) { return *_data._basis; - } else if (type == TRANSFORM) { - return _data._transform->basis; + } else if (type == TRANSFORM3D) { + return _data._transform3d->basis; } else { - return Quat(); + return Quaternion(); } } -Variant::operator Transform() const { - if (type == TRANSFORM) { - return *_data._transform; +Variant::operator Transform3D() const { + if (type == TRANSFORM3D) { + return *_data._transform3d; } else if (type == BASIS) { - return Transform(*_data._basis, Vector3()); - } else if (type == QUAT) { - return Transform(Basis(*reinterpret_cast<const Quat *>(_data._mem)), Vector3()); + return Transform3D(*_data._basis, Vector3()); + } else if (type == QUATERNION) { + return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3()); } else if (type == TRANSFORM2D) { const Transform2D &t = *_data._transform2d; - Transform m; + Transform3D m; m.basis.elements[0][0] = t.elements[0][0]; m.basis.elements[1][0] = t.elements[0][1]; m.basis.elements[0][1] = t.elements[1][0]; @@ -1997,15 +1996,15 @@ Variant::operator Transform() const { m.origin[1] = t.elements[2][1]; return m; } else { - return Transform(); + return Transform3D(); } } Variant::operator Transform2D() const { if (type == TRANSFORM2D) { return *_data._transform2d; - } else if (type == TRANSFORM) { - const Transform &t = *_data._transform; + } else if (type == TRANSFORM3D) { + const Transform3D &t = *_data._transform3d; Transform2D m; m.elements[0][0] = t.basis.elements[0][0]; m.elements[0][1] = t.basis.elements[1][0]; @@ -2495,14 +2494,14 @@ Variant::Variant(const Basis &p_matrix) { _data._basis = memnew(Basis(p_matrix)); } -Variant::Variant(const Quat &p_quat) { - type = QUAT; - memnew_placement(_data._mem, Quat(p_quat)); +Variant::Variant(const Quaternion &p_quaternion) { + type = QUATERNION; + memnew_placement(_data._mem, Quaternion(p_quaternion)); } -Variant::Variant(const Transform &p_transform) { - type = TRANSFORM; - _data._transform = memnew(Transform(p_transform)); +Variant::Variant(const Transform3D &p_transform) { + type = TRANSFORM3D; + _data._transform3d = memnew(Transform3D(p_transform)); } Variant::Variant(const Transform2D &p_transform) { @@ -2739,14 +2738,14 @@ void Variant::operator=(const Variant &p_variant) { case AABB: { *_data._aabb = *(p_variant._data._aabb); } break; - case QUAT: { - *reinterpret_cast<Quat *>(_data._mem) = *reinterpret_cast<const Quat *>(p_variant._data._mem); + case QUATERNION: { + *reinterpret_cast<Quaternion *>(_data._mem) = *reinterpret_cast<const Quaternion *>(p_variant._data._mem); } break; case BASIS: { *_data._basis = *(p_variant._data._basis); } break; - case TRANSFORM: { - *_data._transform = *(p_variant._data._transform); + case TRANSFORM3D: { + *_data._transform3d = *(p_variant._data._transform3d); } break; // misc types @@ -2916,11 +2915,11 @@ uint32_t Variant::hash() const { return hash; } break; - case QUAT: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->x); - hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->y, hash); - hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->z, hash); - return hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->w, hash); + case QUATERNION: { + uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->x); + hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->y, hash); + hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->z, hash); + return hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->w, hash); } break; case BASIS: { @@ -2934,13 +2933,13 @@ uint32_t Variant::hash() const { return hash; } break; - case TRANSFORM: { + case TRANSFORM3D: { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._transform->basis.elements[i][j], hash); + hash = hash_djb2_one_float(_data._transform3d->basis.elements[i][j], hash); } - hash = hash_djb2_one_float(_data._transform->origin[i], hash); + hash = hash_djb2_one_float(_data._transform3d->origin[i], hash); } return hash; @@ -3127,7 +3126,7 @@ uint32_t Variant::hash() const { (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) -#define hash_compare_quat(p_lhs, p_rhs) \ +#define hash_compare_quaternion(p_lhs, p_rhs) \ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \ @@ -3235,11 +3234,11 @@ bool Variant::hash_compare(const Variant &p_variant) const { } break; - case QUAT: { - const Quat *l = reinterpret_cast<const Quat *>(_data._mem); - const Quat *r = reinterpret_cast<const Quat *>(p_variant._data._mem); + case QUATERNION: { + const Quaternion *l = reinterpret_cast<const Quaternion *>(_data._mem); + const Quaternion *r = reinterpret_cast<const Quaternion *>(p_variant._data._mem); - return hash_compare_quat(*l, *r); + return hash_compare_quaternion(*l, *r); } break; case BASIS: { @@ -3255,9 +3254,9 @@ bool Variant::hash_compare(const Variant &p_variant) const { return true; } break; - case TRANSFORM: { - const Transform *l = _data._transform; - const Transform *r = p_variant._data._transform; + case TRANSFORM3D: { + const Transform3D *l = _data._transform3d; + const Transform3D *r = p_variant._data._transform3d; for (int i = 0; i < 3; i++) { if (!(hash_compare_vector3(l->basis.elements[i], r->basis.elements[i]))) { diff --git a/core/variant/variant.h b/core/variant/variant.h index 7f3c3477fc..75316da63f 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -37,9 +37,9 @@ #include "core/math/color.h" #include "core/math/face3.h" #include "core/math/plane.h" -#include "core/math/quat.h" -#include "core/math/transform.h" +#include "core/math/quaternion.h" #include "core/math/transform_2d.h" +#include "core/math/transform_3d.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" #include "core/object/object_id.h" @@ -88,10 +88,10 @@ public: VECTOR3I, TRANSFORM2D, PLANE, - QUAT, + QUATERNION, AABB, BASIS, - TRANSFORM, + TRANSFORM3D, // misc types COLOR, @@ -200,7 +200,7 @@ private: Transform2D *_transform2d; ::AABB *_aabb; Basis *_basis; - Transform *_transform; + Transform3D *_transform3d; PackedArrayRefBase *packed_array; void *_ptr; //generic pointer uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]; @@ -225,7 +225,7 @@ private: false, //VECTOR3I, true, //TRANSFORM2D, false, //PLANE, - false, //QUAT, + false, //QUATERNION, true, //AABB, true, //BASIS, true, //TRANSFORM, @@ -320,10 +320,10 @@ public: operator Vector3i() const; operator Plane() const; operator ::AABB() const; - operator Quat() const; + operator Quaternion() const; operator Basis() const; - operator Transform() const; operator Transform2D() const; + operator Transform3D() const; operator Color() const; operator NodePath() const; @@ -392,10 +392,10 @@ public: Variant(const Vector3i &p_vector3i); Variant(const Plane &p_plane); Variant(const ::AABB &p_aabb); - Variant(const Quat &p_quat); + Variant(const Quaternion &p_quat); Variant(const Basis &p_matrix); Variant(const Transform2D &p_transform); - Variant(const Transform &p_transform); + Variant(const Transform3D &p_transform); Variant(const Color &p_color); Variant(const NodePath &p_node_path); Variant(const ::RID &p_rid); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 063611d415..a1314a11f3 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1419,6 +1419,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, distance_squared_to, sarray("to"), varray()); bind_method(Vector2, length, sarray(), varray()); bind_method(Vector2, length_squared, sarray(), varray()); + bind_method(Vector2, limit_length, sarray("length"), varray(1.0)); bind_method(Vector2, normalized, sarray(), varray()); bind_method(Vector2, is_normalized, sarray(), varray()); bind_method(Vector2, is_equal_approx, sarray("to"), varray()); @@ -1442,14 +1443,15 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, cross, sarray("with"), varray()); bind_method(Vector2, abs, sarray(), varray()); bind_method(Vector2, sign, sarray(), varray()); + bind_method(Vector2, clamp, sarray("min", "max"), varray()); bind_method(Vector2, snapped, sarray("step"), varray()); - bind_method(Vector2, clamped, sarray("length"), varray()); /* Vector2i */ bind_method(Vector2i, aspect, sarray(), varray()); bind_method(Vector2i, sign, sarray(), varray()); bind_method(Vector2i, abs, sarray(), varray()); + bind_method(Vector2i, clamp, sarray("min", "max"), varray()); /* Rect2 */ @@ -1493,10 +1495,12 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, distance_squared_to, sarray("b"), varray()); bind_method(Vector3, length, sarray(), varray()); bind_method(Vector3, length_squared, sarray(), varray()); + bind_method(Vector3, limit_length, sarray("length"), varray(1.0)); bind_method(Vector3, normalized, sarray(), varray()); bind_method(Vector3, is_normalized, sarray(), varray()); bind_method(Vector3, is_equal_approx, sarray("to"), varray()); bind_method(Vector3, inverse, sarray(), varray()); + bind_method(Vector3, clamp, sarray("min", "max"), varray()); bind_method(Vector3, snapped, sarray("step"), varray()); bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray()); bind_method(Vector3, lerp, sarray("to", "weight"), varray()); @@ -1525,6 +1529,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, max_axis, sarray(), varray()); bind_method(Vector3i, sign, sarray(), varray()); bind_method(Vector3i, abs, sarray(), varray()); + bind_method(Vector3i, clamp, sarray("min", "max"), varray()); /* Plane */ @@ -1539,19 +1544,19 @@ static void _register_variant_builtin_methods() { bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray()); bind_methodv(Plane, intersects_segment, &Plane::intersects_segment_bind, sarray("from", "to"), varray()); - /* Quat */ + /* Quaternion */ - bind_method(Quat, length, sarray(), varray()); - bind_method(Quat, length_squared, sarray(), varray()); - bind_method(Quat, normalized, sarray(), varray()); - bind_method(Quat, is_normalized, sarray(), varray()); - bind_method(Quat, is_equal_approx, sarray("to"), varray()); - bind_method(Quat, inverse, sarray(), varray()); - bind_method(Quat, dot, sarray("with"), varray()); - bind_method(Quat, slerp, sarray("to", "weight"), varray()); - bind_method(Quat, slerpni, sarray("to", "weight"), varray()); - bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray()); - bind_method(Quat, get_euler, sarray(), varray()); + bind_method(Quaternion, length, sarray(), varray()); + bind_method(Quaternion, length_squared, sarray(), varray()); + bind_method(Quaternion, normalized, sarray(), varray()); + bind_method(Quaternion, is_normalized, sarray(), varray()); + bind_method(Quaternion, is_equal_approx, sarray("to"), varray()); + bind_method(Quaternion, inverse, sarray(), varray()); + bind_method(Quaternion, dot, sarray("with"), varray()); + bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); + bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); + bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray()); + bind_method(Quaternion, get_euler, sarray(), varray()); /* Color */ @@ -1562,6 +1567,7 @@ static void _register_variant_builtin_methods() { bind_method(Color, to_abgr64, sarray(), varray()); bind_method(Color, to_rgba64, sarray(), varray()); + bind_method(Color, clamp, sarray("min", "max"), varray(Color(0, 0, 0, 0), Color(1, 1, 1, 1))); bind_method(Color, inverted, sarray(), varray()); bind_method(Color, lerp, sarray("to", "weight"), varray()); bind_method(Color, lightened, sarray("amount"), varray()); @@ -1645,6 +1651,8 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform2D, is_equal_approx, sarray("xform"), varray()); + bind_method(Transform2D, set_rotation, sarray("rotation"), varray()); + bind_method(Transform2D, looking_at, sarray("target"), varray(Transform2D())); /* Basis */ @@ -1662,7 +1670,7 @@ static void _register_variant_builtin_methods() { bind_method(Basis, get_orthogonal_index, sarray(), varray()); bind_method(Basis, slerp, sarray("to", "weight"), varray()); bind_method(Basis, is_equal_approx, sarray("b"), varray()); - bind_method(Basis, get_rotation_quat, sarray(), varray()); + bind_method(Basis, get_rotation_quaternion, sarray(), varray()); /* AABB */ @@ -1690,17 +1698,17 @@ static void _register_variant_builtin_methods() { bind_methodv(AABB, intersects_segment, &AABB::intersects_segment_bind, sarray("from", "to"), varray()); bind_methodv(AABB, intersects_ray, &AABB::intersects_ray_bind, sarray("from", "dir"), varray()); - /* Transform */ + /* Transform3D */ - bind_method(Transform, inverse, sarray(), varray()); - bind_method(Transform, affine_inverse, sarray(), varray()); - bind_method(Transform, orthonormalized, sarray(), varray()); - bind_method(Transform, rotated, sarray("axis", "phi"), varray()); - bind_method(Transform, scaled, sarray("scale"), varray()); - bind_method(Transform, translated, sarray("offset"), varray()); - bind_method(Transform, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); - bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray()); - bind_method(Transform, is_equal_approx, sarray("xform"), varray()); + bind_method(Transform3D, inverse, sarray(), varray()); + bind_method(Transform3D, affine_inverse, sarray(), varray()); + bind_method(Transform3D, orthonormalized, sarray(), varray()); + bind_method(Transform3D, rotated, sarray("axis", "phi"), varray()); + bind_method(Transform3D, scaled, sarray("scale"), varray()); + bind_method(Transform3D, translated, sarray("offset"), varray()); + bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); + bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); + bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); /* Dictionary */ @@ -2019,14 +2027,14 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0)); _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0)); - Transform identity_transform = Transform(); - Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); - Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); - Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform); - _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform); + Transform3D identity_transform = Transform3D(); + Transform3D flip_x_transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); + Transform3D flip_y_transform = Transform3D(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); + Transform3D flip_z_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); + _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "IDENTITY", identity_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_X", flip_x_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Y", flip_y_transform); + _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Z", flip_z_transform); Basis identity_basis = Basis(); Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1); @@ -2041,7 +2049,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0)); _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); - _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1)); + _VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1)); } void Variant::_register_variant_methods() { diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index f0c9e52b46..f66f33ef93 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -62,10 +62,10 @@ MAKE_PTRCONSTRUCT(Vector3); MAKE_PTRCONSTRUCT(Vector3i); MAKE_PTRCONSTRUCT(Transform2D); MAKE_PTRCONSTRUCT(Plane); -MAKE_PTRCONSTRUCT(Quat); +MAKE_PTRCONSTRUCT(Quaternion); MAKE_PTRCONSTRUCT(AABB); MAKE_PTRCONSTRUCT(Basis); -MAKE_PTRCONSTRUCT(Transform); +MAKE_PTRCONSTRUCT(Transform3D); MAKE_PTRCONSTRUCT(Color); MAKE_PTRCONSTRUCT(StringName); MAKE_PTRCONSTRUCT(NodePath); @@ -659,13 +659,13 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Plane, Vector3, Vector3, Vector3>>(sarray("point1", "point2", "point3")); add_constructor<VariantConstructor<Plane, double, double, double, double>>(sarray("a", "b", "c", "d")); - add_constructor<VariantConstructNoArgs<Quat>>(sarray()); - add_constructor<VariantConstructor<Quat, Quat>>(sarray("from")); - add_constructor<VariantConstructor<Quat, Basis>>(sarray("from")); - add_constructor<VariantConstructor<Quat, Vector3>>(sarray("euler")); - add_constructor<VariantConstructor<Quat, Vector3, double>>(sarray("axis", "angle")); - add_constructor<VariantConstructor<Quat, Vector3, Vector3>>(sarray("arc_from", "arc_to")); - add_constructor<VariantConstructor<Quat, double, double, double, double>>(sarray("x", "y", "z", "w")); + add_constructor<VariantConstructNoArgs<Quaternion>>(sarray()); + add_constructor<VariantConstructor<Quaternion, Quaternion>>(sarray("from")); + add_constructor<VariantConstructor<Quaternion, Basis>>(sarray("from")); + add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler")); + add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle")); + add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to")); + add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w")); add_constructor<VariantConstructNoArgs<::AABB>>(sarray()); add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from")); @@ -673,15 +673,15 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructNoArgs<Basis>>(sarray()); add_constructor<VariantConstructor<Basis, Basis>>(sarray("from")); - add_constructor<VariantConstructor<Basis, Quat>>(sarray("from")); + add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from")); add_constructor<VariantConstructor<Basis, Vector3>>(sarray("euler")); add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi")); add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis")); - add_constructor<VariantConstructNoArgs<Transform>>(sarray()); - add_constructor<VariantConstructor<Transform, Transform>>(sarray("from")); - add_constructor<VariantConstructor<Transform, Basis, Vector3>>(sarray("basis", "origin")); - add_constructor<VariantConstructor<Transform, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin")); + add_constructor<VariantConstructNoArgs<Transform3D>>(sarray()); + add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from")); + add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin")); + add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin")); add_constructor<VariantConstructNoArgs<Color>>(sarray()); add_constructor<VariantConstructor<Color, Color>>(sarray("from")); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index fb791f8c0c..9e5811a082 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -55,7 +55,7 @@ public: case Variant::BASIS: init_basis(v); break; - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: init_transform(v); break; case Variant::STRING_NAME: @@ -138,14 +138,14 @@ public: _FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; } _FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); } _FORCE_INLINE_ static const Plane *get_plane(const Variant *v) { return reinterpret_cast<const Plane *>(v->_data._mem); } - _FORCE_INLINE_ static Quat *get_quat(Variant *v) { return reinterpret_cast<Quat *>(v->_data._mem); } - _FORCE_INLINE_ static const Quat *get_quat(const Variant *v) { return reinterpret_cast<const Quat *>(v->_data._mem); } + _FORCE_INLINE_ static Quaternion *get_quaternion(Variant *v) { return reinterpret_cast<Quaternion *>(v->_data._mem); } + _FORCE_INLINE_ static const Quaternion *get_quaternion(const Variant *v) { return reinterpret_cast<const Quaternion *>(v->_data._mem); } _FORCE_INLINE_ static ::AABB *get_aabb(Variant *v) { return v->_data._aabb; } _FORCE_INLINE_ static const ::AABB *get_aabb(const Variant *v) { return v->_data._aabb; } _FORCE_INLINE_ static Basis *get_basis(Variant *v) { return v->_data._basis; } _FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; } - _FORCE_INLINE_ static Transform *get_transform(Variant *v) { return v->_data._transform; } - _FORCE_INLINE_ static const Transform *get_transform(const Variant *v) { return v->_data._transform; } + _FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return v->_data._transform3d; } + _FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return v->_data._transform3d; } // Misc types. _FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); } @@ -217,8 +217,8 @@ public: v->type = Variant::BASIS; } _FORCE_INLINE_ static void init_transform(Variant *v) { - v->_data._transform = memnew(Transform); - v->type = Variant::TRANSFORM; + v->_data._transform3d = memnew(Transform3D); + v->type = Variant::TRANSFORM3D; } _FORCE_INLINE_ static void init_string_name(Variant *v) { memnew_placement(v->_data._mem, StringName); @@ -320,12 +320,12 @@ public: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: return get_transform(v); case Variant::TRANSFORM2D: return get_transform2d(v); - case Variant::QUAT: - return get_quat(v); + case Variant::QUATERNION: + return get_quaternion(v); case Variant::PLANE: return get_plane(v); case Variant::BASIS: @@ -398,12 +398,12 @@ public: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: return get_transform(v); case Variant::TRANSFORM2D: return get_transform2d(v); - case Variant::QUAT: - return get_quat(v); + case Variant::QUATERNION: + return get_quaternion(v); case Variant::PLANE: return get_plane(v); case Variant::BASIS: @@ -590,9 +590,9 @@ struct VariantGetInternalPtr<Transform2D> { }; template <> -struct VariantGetInternalPtr<Transform> { - static Transform *get_ptr(Variant *v) { return VariantInternal::get_transform(v); } - static const Transform *get_ptr(const Variant *v) { return VariantInternal::get_transform(v); } +struct VariantGetInternalPtr<Transform3D> { + static Transform3D *get_ptr(Variant *v) { return VariantInternal::get_transform(v); } + static const Transform3D *get_ptr(const Variant *v) { return VariantInternal::get_transform(v); } }; template <> @@ -602,9 +602,9 @@ struct VariantGetInternalPtr<Plane> { }; template <> -struct VariantGetInternalPtr<Quat> { - static Quat *get_ptr(Variant *v) { return VariantInternal::get_quat(v); } - static const Quat *get_ptr(const Variant *v) { return VariantInternal::get_quat(v); } +struct VariantGetInternalPtr<Quaternion> { + static Quaternion *get_ptr(Variant *v) { return VariantInternal::get_quaternion(v); } + static const Quaternion *get_ptr(const Variant *v) { return VariantInternal::get_quaternion(v); } }; template <> @@ -819,9 +819,9 @@ struct VariantInternalAccessor<Transform2D> { }; template <> -struct VariantInternalAccessor<Transform> { - static _FORCE_INLINE_ const Transform &get(const Variant *v) { return *VariantInternal::get_transform(v); } - static _FORCE_INLINE_ void set(Variant *v, const Transform &p_value) { *VariantInternal::get_transform(v) = p_value; } +struct VariantInternalAccessor<Transform3D> { + static _FORCE_INLINE_ const Transform3D &get(const Variant *v) { return *VariantInternal::get_transform(v); } + static _FORCE_INLINE_ void set(Variant *v, const Transform3D &p_value) { *VariantInternal::get_transform(v) = p_value; } }; template <> @@ -831,9 +831,9 @@ struct VariantInternalAccessor<Plane> { }; template <> -struct VariantInternalAccessor<Quat> { - static _FORCE_INLINE_ const Quat &get(const Variant *v) { return *VariantInternal::get_quat(v); } - static _FORCE_INLINE_ void set(Variant *v, const Quat &p_value) { *VariantInternal::get_quat(v) = p_value; } +struct VariantInternalAccessor<Quaternion> { + static _FORCE_INLINE_ const Quaternion &get(const Variant *v) { return *VariantInternal::get_quaternion(v); } + static _FORCE_INLINE_ void set(Variant *v, const Quaternion &p_value) { *VariantInternal::get_quaternion(v) = p_value; } }; template <> @@ -1067,8 +1067,8 @@ struct VariantInitializer<Plane> { }; template <> -struct VariantInitializer<Quat> { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quat>(v); } +struct VariantInitializer<Quaternion> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quaternion>(v); } }; template <> @@ -1082,7 +1082,7 @@ struct VariantInitializer<Basis> { }; template <> -struct VariantInitializer<Transform> { +struct VariantInitializer<Transform3D> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); } }; @@ -1241,8 +1241,8 @@ struct VariantZeroAssigner<Plane> { }; template <> -struct VariantZeroAssigner<Quat> { - static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quat(v) = Quat(); } +struct VariantZeroAssigner<Quaternion> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quaternion(v) = Quaternion(); } }; template <> @@ -1256,8 +1256,8 @@ struct VariantZeroAssigner<Basis> { }; template <> -struct VariantZeroAssigner<Transform> { - static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform(); } +struct VariantZeroAssigner<Transform3D> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform3D(); } }; template <> diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 8cfa793c0e..10d0a83014 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -1395,7 +1395,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I); - register_op<OperatorEvaluatorAdd<Quat, Quat, Quat>>(Variant::OP_ADD, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorAdd<Quaternion, Quaternion, Quaternion>>(Variant::OP_ADD, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY); register_op<OperatorEvaluatorAppendArray<uint8_t>>(Variant::OP_ADD, Variant::PACKED_BYTE_ARRAY, Variant::PACKED_BYTE_ARRAY); @@ -1416,7 +1416,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); - register_op<OperatorEvaluatorSub<Quat, Quat, Quat>>(Variant::OP_SUBTRACT, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorSub<Quaternion, Quaternion, Quaternion>>(Variant::OP_SUBTRACT, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorMul<int64_t, int64_t, int64_t>>(Variant::OP_MULTIPLY, Variant::INT, Variant::INT); @@ -1449,9 +1449,9 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT); register_op<OperatorEvaluatorMul<Vector3i, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT); - register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT); - register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT); - register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT); register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT); @@ -1465,25 +1465,25 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXForm<Vector<Vector2>, Transform2D, Vector<Vector2>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::PACKED_VECTOR2_ARRAY); register_op<OperatorEvaluatorXFormInv<Vector<Vector2>, Vector<Vector2>, Transform2D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR2_ARRAY, Variant::TRANSFORM2D); - register_op<OperatorEvaluatorMul<Transform, Transform, Transform>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::TRANSFORM); - register_op<OperatorEvaluatorXForm<Vector3, Transform, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::VECTOR3); - register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM); - register_op<OperatorEvaluatorXForm<::AABB, Transform, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::AABB); - register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM); - register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::PACKED_VECTOR3_ARRAY); - register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM); + register_op<OperatorEvaluatorMul<Transform3D, Transform3D, Transform3D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<Vector3, Transform3D, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::VECTOR3); + register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB); + register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform3D>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY); + register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorXForm<Vector3, Basis, Vector3>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Basis>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::BASIS); - register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT); - register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT); - register_op<OperatorEvaluatorMul<Quat, int64_t, Quat>>(Variant::OP_MULTIPLY, Variant::INT, Variant::QUAT); - register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT); - register_op<OperatorEvaluatorMul<Quat, double, Quat>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::QUAT); - register_op<OperatorEvaluatorXForm<Vector3, Quat, Vector3>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::VECTOR3); - register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Quat>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::QUAT); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT); + register_op<OperatorEvaluatorMul<Quaternion, int64_t, Quaternion>>(Variant::OP_MULTIPLY, Variant::INT, Variant::QUATERNION); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Quaternion, double, Quaternion>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::QUATERNION); + register_op<OperatorEvaluatorXForm<Vector3, Quaternion, Vector3>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::VECTOR3); + register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Quaternion>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::QUATERNION); register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT); @@ -1516,8 +1516,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT); - register_op<OperatorEvaluatorDiv<Quat, Quat, double>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::FLOAT); - register_op<OperatorEvaluatorDiv<Quat, Quat, int64_t>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::INT); + register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT); register_op<OperatorEvaluatorDiv<Color, Color, Color>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorDiv<Color, Color, double>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::FLOAT); @@ -1544,10 +1544,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I); register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); - register_op<OperatorEvaluatorStringModT<Quat>>(Variant::OP_MODULE, Variant::STRING, Variant::QUAT); + register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION); register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); - register_op<OperatorEvaluatorStringModT<Transform>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM); + register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D); register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR); register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME); @@ -1574,7 +1574,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL); - register_op<OperatorEvaluatorNeg<Quat, Quat>>(Variant::OP_NEGATE, Variant::QUAT, Variant::NIL); + register_op<OperatorEvaluatorNeg<Quaternion, Quaternion>>(Variant::OP_NEGATE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL); @@ -1584,7 +1584,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL); - register_op<OperatorEvaluatorPos<Quat, Quat>>(Variant::OP_POSITIVE, Variant::QUAT, Variant::NIL); + register_op<OperatorEvaluatorPos<Quaternion, Quaternion>>(Variant::OP_POSITIVE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL); @@ -1612,10 +1612,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE); - register_op<OperatorEvaluatorEqual<Quat, Quat>>(Variant::OP_EQUAL, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorEqual<Quaternion, Quaternion>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS); - register_op<OperatorEvaluatorEqual<Transform, Transform>>(Variant::OP_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); + register_op<OperatorEvaluatorEqual<Transform3D, Transform3D>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -1658,10 +1658,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE); - register_op<OperatorEvaluatorNotEqual<Quat, Quat>>(Variant::OP_NOT_EQUAL, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorNotEqual<Quaternion, Quaternion>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS); - register_op<OperatorEvaluatorNotEqual<Transform, Transform>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); + register_op<OperatorEvaluatorNotEqual<Transform3D, Transform3D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -1849,10 +1849,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY); - register_op<OperatorEvaluatorInDictionaryHas<Quat>>(Variant::OP_IN, Variant::QUAT, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Quaternion>>(Variant::OP_IN, Variant::QUATERNION, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY); - register_op<OperatorEvaluatorInDictionaryHas<Transform>>(Variant::OP_IN, Variant::TRANSFORM, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Transform3D>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY); @@ -1886,10 +1886,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY); - register_op<OperatorEvaluatorInArrayFind<Quat, Array>>(Variant::OP_IN, Variant::QUAT, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Quaternion, Array>>(Variant::OP_IN, Variant::QUATERNION, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY); - register_op<OperatorEvaluatorInArrayFind<Transform, Array>>(Variant::OP_IN, Variant::TRANSFORM, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Transform3D, Array>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index edaeddbf27..b58f60c149 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -614,7 +614,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Plane(args[0], args[1], args[2], args[3]); - } else if (id == "Quat") { + } else if (id == "Quaternion" || id == "Quat") { // "Quat" kept for compatibility Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { @@ -626,7 +626,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return ERR_PARSE_ERROR; } - value = Quat(args[0], args[1], args[2], args[3]); + value = Quaternion(args[0], args[1], args[2], args[3]); } else if (id == "AABB" || id == "Rect3") { Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); @@ -653,7 +653,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); - } else if (id == "Transform") { + } else if (id == "Transform3D" || id == "Transform") { // "Transform" kept for compatibility with Godot <4. Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { @@ -665,7 +665,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return ERR_PARSE_ERROR; } - value = Transform(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11])); + value = Transform3D(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11])); } else if (id == "Color") { Vector<float> args; Error err = _parse_construct<float>(p_stream, args, line, r_err_str); @@ -1454,9 +1454,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); } break; - case Variant::QUAT: { - Quat quat = p_variant; - p_store_string_func(p_store_string_ud, "Quat( " + rtosfix(quat.x) + ", " + rtosfix(quat.y) + ", " + rtosfix(quat.z) + ", " + rtosfix(quat.w) + " )"); + case Variant::QUATERNION: { + Quaternion quaternion = p_variant; + p_store_string_func(p_store_string_ud, "Quaternion( " + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + " )"); } break; case Variant::TRANSFORM2D: { @@ -1489,9 +1489,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, s + " )"); } break; - case Variant::TRANSFORM: { - String s = "Transform( "; - Transform t = p_variant; + case Variant::TRANSFORM3D: { + String s = "Transform3D( "; + Transform3D t = p_variant; Basis &m3 = t.basis; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 9ab8602782..4f4a80e807 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -279,17 +279,17 @@ SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) SETGET_STRUCT(Plane, Vector3, normal) SETGET_NUMBER_STRUCT(Plane, double, d) -SETGET_NUMBER_STRUCT(Quat, double, x) -SETGET_NUMBER_STRUCT(Quat, double, y) -SETGET_NUMBER_STRUCT(Quat, double, z) -SETGET_NUMBER_STRUCT(Quat, double, w) +SETGET_NUMBER_STRUCT(Quaternion, double, x) +SETGET_NUMBER_STRUCT(Quaternion, double, y) +SETGET_NUMBER_STRUCT(Quaternion, double, z) +SETGET_NUMBER_STRUCT(Quaternion, double, w) SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) -SETGET_STRUCT(Transform, Basis, basis) -SETGET_STRUCT(Transform, Vector3, origin) +SETGET_STRUCT(Transform3D, Basis, basis) +SETGET_STRUCT(Transform3D, Vector3, origin) SETGET_NUMBER_STRUCT(Color, double, r) SETGET_NUMBER_STRUCT(Color, double, g) @@ -374,17 +374,17 @@ void register_named_setters_getters() { REGISTER_MEMBER(Plane, d); REGISTER_MEMBER(Plane, normal); - REGISTER_MEMBER(Quat, x); - REGISTER_MEMBER(Quat, y); - REGISTER_MEMBER(Quat, z); - REGISTER_MEMBER(Quat, w); + REGISTER_MEMBER(Quaternion, x); + REGISTER_MEMBER(Quaternion, y); + REGISTER_MEMBER(Quaternion, z); + REGISTER_MEMBER(Quaternion, w); REGISTER_MEMBER(Basis, x); REGISTER_MEMBER(Basis, y); REGISTER_MEMBER(Basis, z); - REGISTER_MEMBER(Transform, basis); - REGISTER_MEMBER(Transform, origin); + REGISTER_MEMBER(Transform3D, basis); + REGISTER_MEMBER(Transform3D, origin); REGISTER_MEMBER(Color, r); REGISTER_MEMBER(Color, g); @@ -975,7 +975,7 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) -INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quat, double, real_t, 4) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .elements, 3) @@ -1037,7 +1037,7 @@ void register_indexed_setters_getters() { REGISTER_INDEXED_MEMBER(Vector2i); REGISTER_INDEXED_MEMBER(Vector3); REGISTER_INDEXED_MEMBER(Vector3i); - REGISTER_INDEXED_MEMBER(Quat); + REGISTER_INDEXED_MEMBER(Quaternion); REGISTER_INDEXED_MEMBER(Color); REGISTER_INDEXED_MEMBER(Transform2D); REGISTER_INDEXED_MEMBER(Basis); @@ -2135,10 +2135,10 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c); } return; - case QUAT: { - Quat empty_rot; - const Quat *qa = reinterpret_cast<const Quat *>(a._data._mem); - const Quat *qb = reinterpret_cast<const Quat *>(b._data._mem); + case QUATERNION: { + Quaternion empty_rot; + const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem); + const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem); r_dst = *qa * empty_rot.slerp(*qb, c); } return; @@ -2295,8 +2295,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & r_dst = a; } return; - case QUAT: { - r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c); + case QUATERNION: { + r_dst = reinterpret_cast<const Quaternion *>(a._data._mem)->slerp(*reinterpret_cast<const Quaternion *>(b._data._mem), c); } return; case AABB: { @@ -2304,11 +2304,11 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case BASIS: { - r_dst = Transform(*a._data._basis).interpolate_with(Transform(*b._data._basis), c).basis; + r_dst = Transform3D(*a._data._basis).interpolate_with(Transform3D(*b._data._basis), c).basis; } return; - case TRANSFORM: { - r_dst = a._data._transform->interpolate_with(*b._data._transform, c); + case TRANSFORM3D: { + r_dst = a._data._transform3d->interpolate_with(*b._data._transform3d, c); } return; case COLOR: { diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index e210fa8808..ed0cf5bd5d 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2596,8 +2596,8 @@ <constant name="TYPE_PLANE" value="12" enum="Variant.Type"> Variable is of type [Plane]. </constant> - <constant name="TYPE_QUAT" value="13" enum="Variant.Type"> - Variable is of type [Quat]. + <constant name="TYPE_QUATERNION" value="13" enum="Variant.Type"> + Variable is of type [Quaternion]. </constant> <constant name="TYPE_AABB" value="14" enum="Variant.Type"> Variable is of type [AABB]. @@ -2605,8 +2605,8 @@ <constant name="TYPE_BASIS" value="15" enum="Variant.Type"> Variable is of type [Basis]. </constant> - <constant name="TYPE_TRANSFORM" value="16" enum="Variant.Type"> - Variable is of type [Transform]. + <constant name="TYPE_TRANSFORM3D" value="16" enum="Variant.Type"> + Variable is of type [Transform3D]. </constant> <constant name="TYPE_COLOR" value="17" enum="Variant.Type"> Variable is of type [Color]. diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index a28bde9946..af34a948f5 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -242,7 +242,7 @@ <method name="operator *" qualifiers="operator"> <return type="AABB"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml index f4cf246713..f644606040 100644 --- a/doc/classes/AcceptDialog.xml +++ b/doc/classes/AcceptDialog.xml @@ -49,7 +49,7 @@ <method name="register_text_enter"> <return type="void"> </return> - <argument index="0" name="line_edit" type="Node"> + <argument index="0" name="line_edit" type="Control"> </argument> <description> Registers a [LineEdit] in the dialog. When the enter key is pressed, the dialog will be accepted. diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 7ceb21d22e..02203a3725 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -640,7 +640,7 @@ </argument> <argument index="2" name="location" type="Vector3"> </argument> - <argument index="3" name="rotation" type="Quat"> + <argument index="3" name="rotation" type="Quaternion"> </argument> <argument index="4" name="scale" type="Vector3"> </argument> @@ -656,7 +656,7 @@ <argument index="1" name="time_sec" type="float"> </argument> <description> - Returns the interpolated value of a transform track at a given time (in seconds). An array consisting of 3 elements: position ([Vector3]), rotation ([Quat]) and scale ([Vector3]). + Returns the interpolated value of a transform track at a given time (in seconds). An array consisting of 3 elements: position ([Vector3]), rotation ([Quaternion]) and scale ([Vector3]). </description> </method> <method name="value_track_get_key_indices" qualifiers="const"> @@ -727,8 +727,8 @@ <constant name="TYPE_VALUE" value="0" enum="TrackType"> Value tracks set values in node properties, but only those which can be Interpolated. </constant> - <constant name="TYPE_TRANSFORM" value="1" enum="TrackType"> - Transform tracks are used to change node local transforms or skeleton pose bones. Transitions are interpolated. + <constant name="TYPE_TRANSFORM3D" value="1" enum="TrackType"> + Transform3D tracks are used to change node local transforms or skeleton pose bones of 3D nodes. Transitions are interpolated. </constant> <constant name="TYPE_METHOD" value="2" enum="TrackType"> Method tracks call functions with given arguments per key. diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 2517941133..af7d8d73e8 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -21,10 +21,10 @@ </description> </method> <method name="get_root_motion_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> - Retrieve the motion of the [member root_motion_track] as a [Transform] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_TRANSFORM], returns an identity transformation. + Retrieve the motion of the [member root_motion_track] as a [Transform3D] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_TRANSFORM3D], returns an identity transformation. </description> </method> <method name="rename_parameter"> @@ -50,7 +50,7 @@ </member> <member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath("")"> The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. To specify a track that controls properties or bones, append its name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code]. - If the track has type [constant Animation.TYPE_TRANSFORM], the transformation will be cancelled visually, and the animation will appear to stay in place. + If the track has type [constant Animation.TYPE_TRANSFORM3D], the transformation will be cancelled visually, and the animation will appear to stay in place. </member> <member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root"> The root animation node of this [AnimationTree]. See [AnimationNode]. diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 879b61a880..49775fa28b 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -615,7 +615,7 @@ <argument index="0" name="func" type="Callable"> </argument> <description> - Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. + Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. For two elements [code]a[/code] and [code]b[/code], if the given method returns [code]true[/code], element [code]b[/code] will be after element [code]a[/code] in the array. [b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior. [codeblocks] [gdscript] diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 7c1c4656f8..7826932179 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -113,7 +113,7 @@ <method name="lightmap_unwrap"> <return type="int" enum="Error"> </return> - <argument index="0" name="transform" type="Transform"> + <argument index="0" name="transform" type="Transform3D"> </argument> <argument index="1" name="texel_size" type="float"> </argument> diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index db46ed2778..a1759bd588 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -108,7 +108,7 @@ <member name="unit_db" type="float" setter="set_unit_db" getter="get_unit_db" default="0.0"> The base sound level unaffected by dampening, in decibels. </member> - <member name="unit_size" type="float" setter="set_unit_size" getter="get_unit_size" default="1.0"> + <member name="unit_size" type="float" setter="set_unit_size" getter="get_unit_size" default="10.0"> The factor for the attenuation effect. Higher values make the sound audible over a larger distance. </member> </members> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 0a7b4c5dab..49edb4c691 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -199,7 +199,7 @@ The emitted light's color. See [member emission_enabled]. </member> <member name="emission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> - If [code]true[/code], the body emits light. Emitting light makes the object appear brighter. The object can also cast light on other objects if a [GIProbe] is used and this object is used in baked lighting. + If [code]true[/code], the body emits light. Emitting light makes the object appear brighter. The object can also cast light on other objects if a [VoxelGI] is used and this object is used in baked lighting. </member> <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0"> The emitted light's strength. See [member emission_enabled]. @@ -671,10 +671,7 @@ <constant name="DIFFUSE_LAMBERT_WRAP" value="2" enum="DiffuseMode"> Extends Lambert to cover more than 90 degrees when roughness increases. </constant> - <constant name="DIFFUSE_OREN_NAYAR" value="3" enum="DiffuseMode"> - Attempts to use roughness to emulate microsurfacing. - </constant> - <constant name="DIFFUSE_TOON" value="4" enum="DiffuseMode"> + <constant name="DIFFUSE_TOON" value="3" enum="DiffuseMode"> Uses a hard cut for lighting, with smoothing affected by roughness. </constant> <constant name="SPECULAR_SCHLICK_GGX" value="0" enum="SpecularMode"> diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 55ae58ee3a..14fca04672 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -4,7 +4,7 @@ 3×3 matrix datatype. </brief_description> <description> - 3×3 matrix used for 3D rotation and scale. Almost always used as an orthogonal basis for a Transform. + 3×3 matrix used for 3D rotation and scale. Almost always used as an orthogonal basis for a [Transform3D]. Contains 3 vector fields X, Y and Z as its columns, which are typically interpreted as the local basis vectors of a transformation. For such use, it is composed of a scaling and a rotation matrix, in that order (M = R.S). Can also be accessed as array of 3D vectors. These vectors are normally orthogonal to each other, but are not necessarily normalized (due to scaling). For more information, read the "Matrices and transforms" documentation article. @@ -53,13 +53,13 @@ </argument> <description> Constructs a pure rotation basis matrix from the given Euler angles (in the YXZ convention: when *composing*, first Y, then X, and Z last), given in the vector format as (X angle, Y angle, Z angle). - Consider using the [Quat] constructor instead, which uses a quaternion instead of Euler angles. + Consider using the [Quaternion] constructor instead, which uses a quaternion instead of Euler angles. </description> </method> <method name="Basis" qualifiers="constructor"> <return type="Basis"> </return> - <argument index="0" name="from" type="Quat"> + <argument index="0" name="from" type="Quaternion"> </argument> <description> Constructs a pure rotation basis matrix from the given quaternion. @@ -91,7 +91,7 @@ </return> <description> Returns the basis's rotation in the form of Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last). The returned vector contains the rotation angles in the format (X angle, Y angle, Z angle). - Consider using the [method get_rotation_quat] method instead, which returns a [Quat] quaternion instead of Euler angles. + Consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion] quaternion instead of Euler angles. </description> </method> <method name="get_orthogonal_index" qualifiers="const"> @@ -101,8 +101,8 @@ This function considers a discretization of rotations into 24 points on unit sphere, lying along the vectors (x,y,z) with each component being either -1, 0, or 1, and returns the index of the point best representing the orientation of the object. It is mainly used by the [GridMap] editor. For further details, refer to the Godot source code. </description> </method> - <method name="get_rotation_quat" qualifiers="const"> - <return type="Quat"> + <method name="get_rotation_quaternion" qualifiers="const"> + <return type="Quaternion"> </return> <description> Returns the basis's rotation in the form of a quaternion. See [method get_euler] if you need Euler angles, but keep in mind quaternions should generally be preferred to Euler angles. diff --git a/doc/classes/Bone2D.xml b/doc/classes/Bone2D.xml index 910d488dfd..93744ddad7 100644 --- a/doc/classes/Bone2D.xml +++ b/doc/classes/Bone2D.xml @@ -19,6 +19,28 @@ Stores the node's current transforms in [member rest]. </description> </method> + <method name="get_autocalculate_length_and_angle" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether this [code]Bone2D[/code] node is going to autocalculate its length and bone angle using its first [code]Bone2D[/code] child node, if one exists. If there are no [code]Bone2D[/code] children, then it cannot autocalculate these values and will print a warning. + </description> + </method> + <method name="get_bone_angle" qualifiers="const"> + <return type="float"> + </return> + <description> + Returns the angle of the bone in the [code]Bone2D[/code] node. + [b]Note:[/b] This is different from the [code]Bone2D[/code]'s rotation. The bone angle is the rotation of the bone shown by the [code]Bone2D[/code] gizmo, and because [code]Bone2D[/code] bones are based on positions, this can vary from the actual rotation of the [code]Bone2D[/code] node. + </description> + </method> + <method name="get_default_length" qualifiers="const"> + <return type="float"> + </return> + <description> + Deprecated. Please use [code]get_length[/code] instead. + </description> + </method> <method name="get_index_in_skeleton" qualifiers="const"> <return type="int"> </return> @@ -26,6 +48,13 @@ Returns the node's index as part of the entire skeleton. See [Skeleton2D]. </description> </method> + <method name="get_length" qualifiers="const"> + <return type="float"> + </return> + <description> + Returns the length of the bone in the [code]Bone2D[/code] node. + </description> + </method> <method name="get_skeleton_rest" qualifiers="const"> <return type="Transform2D"> </return> @@ -33,11 +62,45 @@ Returns the node's [member rest] [code]Transform2D[/code] if it doesn't have a parent, or its rest pose relative to its parent. </description> </method> + <method name="set_autocalculate_length_and_angle"> + <return type="void"> + </return> + <argument index="0" name="auto_calculate" type="bool"> + </argument> + <description> + When set to [code]true[/code], the [code]Bone2D[/code] node will attempt to automatically calculate the bone angle and length using the first child [code]Bone2D[/code] node, if one exists. If none exist, the [code]Bone2D[/code] cannot automatically calculate these values and will print a warning. + </description> + </method> + <method name="set_bone_angle"> + <return type="void"> + </return> + <argument index="0" name="angle" type="float"> + </argument> + <description> + Sets the bone angle for the [code]Bone2D[/code] node. This is typically set to the rotation from the [code]Bone2D[/code] node to a child [code]Bone2D[/code] node. + [b]Note:[/b] This is different from the [code]Bone2D[/code]'s rotation. The bone angle is the rotation of the bone shown by the [code]Bone2D[/code] gizmo, and because [code]Bone2D[/code] bones are based on positions, this can vary from the actual rotation of the [code]Bone2D[/code] node. + </description> + </method> + <method name="set_default_length"> + <return type="void"> + </return> + <argument index="0" name="default_length" type="float"> + </argument> + <description> + Deprecated. Please use [code]set_length[/code] instead. + </description> + </method> + <method name="set_length"> + <return type="void"> + </return> + <argument index="0" name="length" type="float"> + </argument> + <description> + Sets the length of the bone in the [code]Bone2D[/code] node. + </description> + </method> </methods> <members> - <member name="default_length" type="float" setter="set_default_length" getter="get_default_length" default="16.0"> - Length of the bone's representation drawn in the editor's viewport in pixels. - </member> <member name="rest" type="Transform2D" setter="set_rest" getter="get_rest" default="Transform2D( 0, 0, 0, 0, 0, 0 )"> Rest transform of the bone. You can reset the node's transforms to this value using [method apply_rest]. </member> diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 9f1d6d8e31..30f6c2b951 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -27,7 +27,7 @@ </description> </method> <method name="get_camera_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Gets the camera transform. Subclassed cameras such as [ClippedCamera3D] may provide different transforms than the [Node] transform. diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml new file mode 100644 index 0000000000..0e6ca073a7 --- /dev/null +++ b/doc/classes/CharacterBody2D.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CharacterBody2D" inherits="PhysicsBody2D" version="4.0"> + <brief_description> + Character body 2D node. + </brief_description> + <description> + Character bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a rigid body, these are the same as a static body. However, they have two main uses: + [b]Kinematic characters:[/b] Character bodies have an API for moving objects with walls and slopes detection ([method move_and_slide] method), in addition to collision detection (also done with [method PhysicsBody3D.move_and_collide]). This makes them really useful to implement characters that move in specific ways and collide with the world, but don't require advanced physics. + [b]Kinematic motion:[/b] Character bodies can also be used for kinematic motion (same functionality as [member StaticBody3D.kinematic_motion] when enabled), which allows them to be moved by code and push other bodies on their path. + </description> + <tutorials> + <link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link> + <link title="Using KinematicBody2D">https://docs.godotengine.org/en/latest/tutorials/physics/using_kinematic_body_2d.html</link> + <link title="2D Kinematic Character Demo">https://godotengine.org/asset-library/asset/113</link> + <link title="2D Platformer Demo">https://godotengine.org/asset-library/asset/120</link> + </tutorials> + <methods> + <method name="get_floor_normal" qualifiers="const"> + <return type="Vector2"> + </return> + <description> + Returns the surface normal of the floor at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code]. + </description> + </method> + <method name="get_floor_velocity" qualifiers="const"> + <return type="Vector2"> + </return> + <description> + Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code]. + </description> + </method> + <method name="get_slide_collision"> + <return type="KinematicCollision2D"> + </return> + <argument index="0" name="slide_idx" type="int"> + </argument> + <description> + Returns a [KinematicCollision2D], which contains information about a collision that occurred during the last call to [method move_and_slide]. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). + [b]Example usage:[/b] + [codeblocks] + [gdscript] + for i in get_slide_count(): + var collision = get_slide_collision(i) + print("Collided with: ", collision.collider.name) + [/gdscript] + [csharp] + for (int i = 0; i < GetSlideCount(); i++) + { + KinematicCollision2D collision = GetSlideCollision(i); + GD.Print("Collided with: ", (collision.Collider as Node).Name); + } + [/csharp] + [/codeblocks] + </description> + </method> + <method name="get_slide_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of times the body collided and changed direction during the last call to [method move_and_slide]. + </description> + </method> + <method name="is_on_ceiling" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="is_on_floor" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="is_on_wall" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="move_and_slide"> + <return type="void"> + </return> + <description> + Moves the body based on [member linear_velocity]. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [CharacterBody2D] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. + This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. + Modifies [member linear_velocity] if a slide collision occurred. To get detailed information about collisions that occurred, use [method get_slide_collision]. + </description> + </method> + </methods> + <members> + <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.08"> + Extra margin used for collision recovery when calling [method move_and_slide]. + If the body is at least this close to another body, it will consider them to be colliding and will be pushed away before performing the actual motion. + A higher value means it's more flexible for detecting collision, which helps with consistently detecting walls and floors. + A lower value forces the collision algorithm to use more exact detection, so it can be used in cases that specifically require precision, e.g at very low scale to avoid visible jittering, or for stability with a stack of character bodies. + </member> + <member name="floor_max_angle" type="float" setter="set_floor_max_angle" getter="get_floor_max_angle" default="0.785398"> + Maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. The default value equals 45 degrees. + </member> + <member name="floor_max_angle_degrees" type="float" setter="set_floor_max_angle_degrees" getter="get_floor_max_angle_degrees" default="45.0"> + Maximum angle (in degrees) where a slope is still considered a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. + </member> + <member name="infinite_inertia" type="bool" setter="set_infinite_inertia_enabled" getter="is_infinite_inertia_enabled" default="true"> + If [code]true[/code], the body will be able to push [RigidBody2D] nodes when calling [method move_and_slide], but it also won't detect any collisions with them. If [code]false[/code], it will interact with [RigidBody2D] nodes like with [StaticBody2D]. + </member> + <member name="linear_velocity" type="Vector2" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector2( 0, 0 )"> + Current velocity vector in pixels per second, used and modified during calls to [method move_and_slide]. + </member> + <member name="max_slides" type="int" setter="set_max_slides" getter="get_max_slides" default="4"> + Maximum number of times the body can change direction before it stops when calling [method move_and_slide]. + </member> + <member name="motion/sync_to_physics" type="bool" setter="set_sync_to_physics" getter="is_sync_to_physics_enabled" default="false"> + If [code]true[/code], the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms. Do [b]not[/b] use together with [method move_and_slide] or [method PhysicsBody2D.move_and_collide] functions. + </member> + <member name="snap" type="Vector2" setter="set_snap" getter="get_snap" default="Vector2( 0, 0 )"> + When set to a value different from [code]Vector2(0, 0)[/code], the body is kept attached to slopes when calling [method move_and_slide]. + As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting [code]snap[/code] to [code]Vector2(0, 0)[/code]. + </member> + <member name="stop_on_slope" type="bool" setter="set_stop_on_slope_enabled" getter="is_stop_on_slope_enabled" default="false"> + If [code]true[/code], the body will not slide on slopes when you include gravity in [code]linear_velocity[/code] when calling [method move_and_slide] and the body is standing still. + </member> + <member name="up_direction" type="Vector2" setter="set_up_direction" getter="get_up_direction" default="Vector2( 0, -1 )"> + Direction vector used to determine what is a wall and what is a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. Defaults to [code]Vector2.UP[/code]. If set to [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml new file mode 100644 index 0000000000..790edfcad1 --- /dev/null +++ b/doc/classes/CharacterBody3D.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="CharacterBody3D" inherits="PhysicsBody3D" version="4.0"> + <brief_description> + Character body 3D node. + </brief_description> + <description> + Character bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a rigid body, these are the same as a static body. However, they have two main uses: + [b]Kinematic characters:[/b] Character bodies have an API for moving objects with walls and slopes detection ([method move_and_slide] method), in addition to collision detection (also done with [method PhysicsBody3D.move_and_collide]). This makes them really useful to implement characters that move in specific ways and collide with the world, but don't require advanced physics. + [b]Kinematic motion:[/b] Character bodies can also be used for kinematic motion (same functionality as [member StaticBody3D.kinematic_motion] when enabled), which allows them to be moved by code and push other bodies on their path. + </description> + <tutorials> + <link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link> + <link title="3D Kinematic Character Demo">https://godotengine.org/asset-library/asset/126</link> + <link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link> + <link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link> + <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> + </tutorials> + <methods> + <method name="get_floor_normal" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + Returns the surface normal of the floor at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code]. + </description> + </method> + <method name="get_floor_velocity" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code]. + </description> + </method> + <method name="get_slide_collision"> + <return type="KinematicCollision3D"> + </return> + <argument index="0" name="slide_idx" type="int"> + </argument> + <description> + Returns a [KinematicCollision3D], which contains information about a collision that occurred during the last call to [method move_and_slide]. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). + </description> + </method> + <method name="get_slide_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of times the body collided and changed direction during the last call to [method move_and_slide]. + </description> + </method> + <method name="is_on_ceiling" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="is_on_floor" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="is_on_wall" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. + </description> + </method> + <method name="move_and_slide"> + <return type="void"> + </return> + <description> + Moves the body based on [member linear_velocity]. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [CharacterBody3D] or [RigidBody3D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. + This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. + Modifies [member linear_velocity] if a slide collision occurred. To get detailed information about collisions that occurred, use [method get_slide_collision]. + </description> + </method> + </methods> + <members> + <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.001"> + Extra margin used for collision recovery when calling [method move_and_slide]. + If the body is at least this close to another body, it will consider them to be colliding and will be pushed away before performing the actual motion. + A higher value means it's more flexible for detecting collision, which helps with consistently detecting walls and floors. + A lower value forces the collision algorithm to use more exact detection, so it can be used in cases that specifically require precision, e.g at very low scale to avoid visible jittering, or for stability with a stack of character bodies. + </member> + <member name="floor_max_angle" type="float" setter="set_floor_max_angle" getter="get_floor_max_angle" default="0.785398"> + Maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. The default value equals 45 degrees. + </member> + <member name="floor_max_angle_degrees" type="float" setter="set_floor_max_angle_degrees" getter="get_floor_max_angle_degrees" default="45.0"> + Maximum angle (in degrees) where a slope is still considered a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. + </member> + <member name="infinite_inertia" type="bool" setter="set_infinite_inertia_enabled" getter="is_infinite_inertia_enabled" default="true"> + If [code]true[/code], the body will be able to push [RigidBody3D] nodes when calling [method move_and_slide], but it also won't detect any collisions with them. If [code]false[/code], it will interact with [RigidBody3D] nodes like with [StaticBody3D]. + </member> + <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3( 0, 0, 0 )"> + Current velocity vector (typically meters per second), used and modified during calls to [method move_and_slide]. + </member> + <member name="max_slides" type="int" setter="set_max_slides" getter="get_max_slides" default="4"> + Maximum number of times the body can change direction before it stops when calling [method move_and_slide]. + </member> + <member name="snap" type="Vector3" setter="set_snap" getter="get_snap" default="Vector3( 0, 0, 0 )"> + When set to a value different from [code]Vector3(0, 0, 0)[/code], the body is kept attached to slopes when calling [method move_and_slide]. + As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting [code]snap[/code] to [code]Vector3(0, 0, 0)[/code]. + </member> + <member name="stop_on_slope" type="bool" setter="set_stop_on_slope_enabled" getter="is_stop_on_slope_enabled" default="false"> + If [code]true[/code], the body will not slide on slopes when you include gravity in [code]linear_velocity[/code] when calling [method move_and_slide] and the body is standing still. + </member> + <member name="up_direction" type="Vector3" setter="set_up_direction" getter="get_up_direction" default="Vector3( 0, 1, 0 )"> + Direction vector used to determine what is a wall and what is a floor (or a ceiling), rather than a wall, when calling [method move_and_slide]. Defaults to [code]Vector3.UP[/code]. If set to [code]Vector3(0, 0, 0)[/code], everything is considered a wall. This is useful for topdown games. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml index 522eec5cbe..4ab37f5c7b 100644 --- a/doc/classes/CollisionObject3D.xml +++ b/doc/classes/CollisionObject3D.xml @@ -16,14 +16,14 @@ </argument> <argument index="1" name="event" type="InputEvent"> </argument> - <argument index="2" name="click_position" type="Vector3"> + <argument index="2" name="position" type="Vector3"> </argument> - <argument index="3" name="click_normal" type="Vector3"> + <argument index="3" name="normal" type="Vector3"> </argument> <argument index="4" name="shape_idx" type="int"> </argument> <description> - Accepts unhandled [InputEvent]s. [code]click_position[/code] is the clicked location in world space and [code]click_normal[/code] is the normal vector extending from the clicked surface of the [Shape3D] at [code]shape_idx[/code]. Connect to the [code]input_event[/code] signal to easily pick up these events. + Receives unhandled [InputEvent]s. [code]position[/code] is the location in world space of the mouse pointer on the surface of the shape with index [code]shape_idx[/code] and [code]normal[/code] is the normal vector of the surface at that point. Connect to the [signal input_event] signal to easily pick up these events. </description> </method> <method name="create_shape_owner"> @@ -179,12 +179,12 @@ </description> </method> <method name="shape_owner_get_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="owner_id" type="int"> </argument> <description> - Returns the shape owner's [Transform]. + Returns the shape owner's [Transform3D]. </description> </method> <method name="shape_owner_remove_shape"> @@ -214,10 +214,10 @@ </return> <argument index="0" name="owner_id" type="int"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> - Sets the [Transform] of the given shape owner. + Sets the [Transform3D] of the given shape owner. </description> </method> </methods> @@ -243,14 +243,14 @@ </argument> <argument index="1" name="event" type="InputEvent"> </argument> - <argument index="2" name="click_position" type="Vector3"> + <argument index="2" name="position" type="Vector3"> </argument> - <argument index="3" name="click_normal" type="Vector3"> + <argument index="3" name="normal" type="Vector3"> </argument> <argument index="4" name="shape_idx" type="int"> </argument> <description> - Emitted when [method _input_event] receives an event. See its description for details. + Emitted when the object receives an unhandled [InputEvent]. [code]position[/code] is the location in world space of the mouse pointer on the surface of the shape with index [code]shape_idx[/code] and [code]normal[/code] is the normal vector of the surface at that point. </description> </signal> <signal name="mouse_entered"> diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 6133bb8d8c..ddff92e6fc 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -136,6 +136,17 @@ [/codeblocks] </description> </method> + <method name="clamp" qualifiers="const"> + <return type="Color"> + </return> + <argument index="0" name="min" type="Color" default="Color( 0, 0, 0, 0 )"> + </argument> + <argument index="1" name="max" type="Color" default="Color( 1, 1, 1, 1 )"> + </argument> + <description> + Returns a new color with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> <method name="darkened" qualifiers="const"> <return type="Color"> </return> diff --git a/doc/classes/ConcavePolygonShape3D.xml b/doc/classes/ConcavePolygonShape3D.xml index a9687abedc..b510905d1f 100644 --- a/doc/classes/ConcavePolygonShape3D.xml +++ b/doc/classes/ConcavePolygonShape3D.xml @@ -5,7 +5,7 @@ </brief_description> <description> Concave polygon shape resource, which can be set into a [PhysicsBody3D] or area. This shape is created by feeding a list of triangles. - Note: when used for collision, [ConcavePolygonShape3D] is intended to work with static [PhysicsBody3D] nodes like [StaticBody3D] and will not work with [KinematicBody3D] or [RigidBody3D] with a mode other than Static. + Note: when used for collision, [ConcavePolygonShape3D] is intended to work with static [PhysicsBody3D] nodes like [StaticBody3D] and will not work with [CharacterBody3D] or [RigidBody3D] with a mode other than Static. </description> <tutorials> <link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index a9a230b78f..12344712a0 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -1055,7 +1055,7 @@ Anchors the right edge of the node to the origin, the center or the end of its parent control. It changes how the right offset updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience. </member> <member name="anchor_top" type="float" setter="_set_anchor" getter="get_anchor" default="0.0"> - Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top offset updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience. + Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top offset updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience. </member> <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0"> The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals. @@ -1067,7 +1067,7 @@ Tells Godot which node it should give keyboard focus to if the user presses the left arrow on the keyboard or left on a gamepad by default. You can change the key by editing the [code]ui_left[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the left of this one. </member> <member name="focus_neighbor_right" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath("")"> - Tells Godot which node it should give keyboard focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [code]ui_right[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one. + Tells Godot which node it should give keyboard focus to if the user presses the right arrow on the keyboard or right on a gamepad by default. You can change the key by editing the [code]ui_right[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one. </member> <member name="focus_neighbor_top" type="NodePath" setter="set_focus_neighbor" getter="get_focus_neighbor" default="NodePath("")"> Tells Godot which node it should give keyboard focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [code]ui_top[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one. diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 0c9df071a7..6c1cd37beb 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1044,12 +1044,20 @@ <constant name="FEATURE_SWAP_BUFFERS" value="17" enum="Feature"> </constant> <constant name="MOUSE_MODE_VISIBLE" value="0" enum="MouseMode"> + Makes the mouse cursor visible if it is hidden. </constant> <constant name="MOUSE_MODE_HIDDEN" value="1" enum="MouseMode"> + Makes the mouse cursor hidden if it is visible. </constant> <constant name="MOUSE_MODE_CAPTURED" value="2" enum="MouseMode"> + Captures the mouse. The mouse will be hidden and its position locked at the center of the screen. + [b]Note:[/b] If you want to process the mouse's movement in this mode, you need to use [member InputEventMouseMotion.relative]. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it visible. + </constant> + <constant name="MOUSE_MODE_CONFINED_HIDDEN" value="4" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it hidden. </constant> <constant name="SCREEN_OF_MAIN_WINDOW" value="-1"> </constant> diff --git a/doc/classes/EditorDebuggerPlugin.xml b/doc/classes/EditorDebuggerPlugin.xml index b97933e582..9484d33252 100644 --- a/doc/classes/EditorDebuggerPlugin.xml +++ b/doc/classes/EditorDebuggerPlugin.xml @@ -38,7 +38,7 @@ <return type="bool"> </return> <description> - Returns [code]true[/code] if there is an instance of the game running with the attached debugger otherwise [code]false[/code]. + Returns [code]true[/code] if there is an instance of the game running with the attached debugger otherwise [code]false[/code]. </description> </method> <method name="register_message_capture"> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index aa64ab4043..663eb0ff5c 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -92,7 +92,7 @@ return new Godot.Collections.Array{new Godot.Collections.Dictionary{{"name", "myOption"}, {"defaultValue", false}}}; } - public override int Import(String sourceFile, String savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles) + public override int Import(String sourceFile, String savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles) { var file = new File(); if (file.Open(sourceFile, File.ModeFlags.Read) != Error.Ok) diff --git a/doc/classes/EditorPaths.xml b/doc/classes/EditorPaths.xml index b92927fd53..d0d785dbb8 100644 --- a/doc/classes/EditorPaths.xml +++ b/doc/classes/EditorPaths.xml @@ -31,12 +31,6 @@ <description> </description> </method> - <method name="get_settings_dir" qualifiers="const"> - <return type="String"> - </return> - <description> - </description> - </method> <method name="is_self_contained" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index f6f51df7c0..6c40b7aa9d 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -91,7 +91,8 @@ <argument index="0" name="plugin" type="EditorExportPlugin"> </argument> <description> - Registers a new export plugin. Export plugins are used when the project is being exported. See [EditorExportPlugin] for more information. + Registers a new [EditorExportPlugin]. Export plugins are used to perform tasks when the project is being exported. + See [method add_inspector_plugin] for an example of how to register a plugin. </description> </method> <method name="add_import_plugin"> @@ -100,6 +101,9 @@ <argument index="0" name="importer" type="EditorImportPlugin"> </argument> <description> + Registers a new [EditorImportPlugin]. Import plugins are used to import custom and unsupported assets as a custom [Resource] type. + [b]Note:[/b] If you want to import custom 3D asset formats use [method add_scene_import_plugin] instead. + See [method add_inspector_plugin] for an example of how to register a plugin. </description> </method> <method name="add_inspector_plugin"> @@ -108,6 +112,20 @@ <argument index="0" name="plugin" type="EditorInspectorPlugin"> </argument> <description> + Registers a new [EditorInspectorPlugin]. Inspector plugins are used to extend [EditorInspector] and provide custom configuration tools for your object's properties. + [b]Note:[/b] Always use [method remove_inspector_plugin] to remove the registered [EditorInspectorPlugin] when your [EditorPlugin] is disabled to prevent leaks and an unexpected behavior. + [codeblocks] + [gdscript] + const MyInspectorPlugin = preload("res://addons/your_addon/path/to/your/script.gd") + var inspector_plugin = MyInspectorPlugin.new() + + func _enter_tree(): + add_inspector_plugin(inspector_plugin) + + func _exit_tree(): + remove_inspector_plugin(inspector_plugin) + [/gdscript] + [/codeblocks] </description> </method> <method name="add_scene_import_plugin"> @@ -116,6 +134,7 @@ <argument index="0" name="scene_importer" type="EditorSceneImporter"> </argument> <description> + Registers a new [EditorSceneImporter]. Scene importers are used to import custom 3D asset formats as scenes. </description> </method> <method name="add_spatial_gizmo_plugin"> @@ -124,6 +143,8 @@ <argument index="0" name="plugin" type="EditorNode3DGizmoPlugin"> </argument> <description> + Registers a new [EditorNode3DGizmoPlugin]. Gizmo plugins are used to add custom gizmos to the 3D preview viewport for a [Node3D]. + See [method add_inspector_plugin] for an example of how to register a plugin. </description> </method> <method name="add_tool_menu_item"> @@ -580,6 +601,7 @@ <argument index="0" name="plugin" type="EditorExportPlugin"> </argument> <description> + Removes an export plugin registered by [method add_export_plugin]. </description> </method> <method name="remove_import_plugin"> @@ -588,6 +610,7 @@ <argument index="0" name="importer" type="EditorImportPlugin"> </argument> <description> + Removes an import plugin registered by [method add_import_plugin]. </description> </method> <method name="remove_inspector_plugin"> @@ -596,6 +619,7 @@ <argument index="0" name="plugin" type="EditorInspectorPlugin"> </argument> <description> + Removes an inspector plugin registered by [method add_import_plugin] </description> </method> <method name="remove_scene_import_plugin"> @@ -604,6 +628,7 @@ <argument index="0" name="scene_importer" type="EditorSceneImporter"> </argument> <description> + Removes a scene importer registered by [method add_scene_import_plugin]. </description> </method> <method name="remove_spatial_gizmo_plugin"> @@ -612,6 +637,7 @@ <argument index="0" name="plugin" type="EditorNode3DGizmoPlugin"> </argument> <description> + Removes a gizmo plugin registered by [method add_spatial_gizmo_plugin]. </description> </method> <method name="remove_tool_menu_item"> @@ -629,7 +655,7 @@ <argument index="0" name="parser" type="EditorTranslationParserPlugin"> </argument> <description> - Removes a registered custom translation parser plugin. + Removes a custom translation parser plugin registered by [method add_translation_parser_plugin]. </description> </method> <method name="remove_undo_redo_inspector_hook_callback"> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 6909fac2b7..878535a08d 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -206,7 +206,7 @@ The depth tolerance for screen-space reflections. </member> <member name="ss_reflections_enabled" type="bool" setter="set_ssr_enabled" getter="is_ssr_enabled" default="false"> - If [code]true[/code], screen-space reflections are enabled. Screen-space reflections are more accurate than reflections from [GIProbe]s or [ReflectionProbe]s, but are slower and can't reflect surfaces occluded by others. + If [code]true[/code], screen-space reflections are enabled. Screen-space reflections are more accurate than reflections from [VoxelGI]s or [ReflectionProbe]s, but are slower and can't reflect surfaces occluded by others. </member> <member name="ss_reflections_fade_in" type="float" setter="set_ssr_fade_in" getter="get_ssr_fade_in" default="0.15"> The fade-in distance for screen-space reflections. Affects the area from the reflected material to the screen-space reflection). diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 2206730523..ea3b82dc54 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -490,10 +490,10 @@ </method> </methods> <members> - <member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap" default="false"> + <member name="big_endian" type="bool" setter="set_big_endian" getter="is_big_endian" default="false"> If [code]true[/code], the file is read with big-endian [url=https://en.wikipedia.org/wiki/Endianness]endianness[/url]. If [code]false[/code], the file is read with little-endian endianness. If in doubt, leave this to [code]false[/code] as most files are written with little-endian endianness. - [b]Note:[/b] [member endian_swap] is only about the file format, not the CPU type. The CPU endianness doesn't affect the default endianness for files written. - [b]Note:[/b] This is always reset to [code]false[/code] whenever you open the file. Therefore, you must set [member endian_swap] [i]after[/i] opening the file, not before. + [b]Note:[/b] [member big_endian] is only about the file format, not the CPU type. The CPU endianness doesn't affect the default endianness for files written. + [b]Note:[/b] This is always reset to [code]false[/code] whenever you open the file. Therefore, you must set [member big_endian] [i]after[/i] opening the file, not before. </member> </members> <constants> diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index 76f0fdb406..47bdd9d745 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -22,7 +22,7 @@ <method name="emit_particle"> <return type="void"> </return> - <argument index="0" name="xform" type="Transform"> + <argument index="0" name="xform" type="Transform3D"> </argument> <argument index="1" name="velocity" type="Vector3"> </argument> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index d7408cd0ff..ebfd32c5fb 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -449,7 +449,10 @@ [b]Note:[/b] If you want to process the mouse's movement in this mode, you need to use [member InputEventMouseMotion.relative]. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> - Makes the mouse cursor visible but confines it to the game window. + Confines the mouse cursor to the game window, and make it visible. + </constant> + <constant name="MOUSE_MODE_CONFINED_HIDDEN" value="4" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it hidden. </constant> <constant name="CURSOR_ARROW" value="0" enum="CursorShape"> Arrow cursor. Standard, default pointing cursor. diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml deleted file mode 100644 index fdd4db6115..0000000000 --- a/doc/classes/KinematicBody2D.xml +++ /dev/null @@ -1,176 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicBody2D" inherits="PhysicsBody2D" version="4.0"> - <brief_description> - Kinematic body 2D node. - </brief_description> - <description> - Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses: - [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). - [b]Kinematic characters:[/b] KinematicBody2D also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but don't require advanced physics. - </description> - <tutorials> - <link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link> - <link title="Using KinematicBody2D">https://docs.godotengine.org/en/latest/tutorials/physics/using_kinematic_body_2d.html</link> - <link title="2D Kinematic Character Demo">https://godotengine.org/asset-library/asset/113</link> - <link title="2D Platformer Demo">https://godotengine.org/asset-library/asset/120</link> - </tutorials> - <methods> - <method name="get_floor_normal" qualifiers="const"> - <return type="Vector2"> - </return> - <description> - Returns the surface normal of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code]. - </description> - </method> - <method name="get_floor_velocity" qualifiers="const"> - <return type="Vector2"> - </return> - <description> - Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code]. - </description> - </method> - <method name="get_slide_collision"> - <return type="KinematicCollision2D"> - </return> - <argument index="0" name="slide_idx" type="int"> - </argument> - <description> - Returns a [KinematicCollision2D], which contains information about a collision that occurred during the last call to [method move_and_slide] or [method move_and_slide_with_snap]. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). - [b]Example usage:[/b] - [codeblocks] - [gdscript] - for i in get_slide_count(): - var collision = get_slide_collision(i) - print("Collided with: ", collision.collider.name) - [/gdscript] - [csharp] - for (int i = 0; i < GetSlideCount(); i++) - { - KinematicCollision2D collision = GetSlideCollision(i); - GD.Print("Collided with: ", (collision.Collider as Node).Name); - } - [/csharp] - [/codeblocks] - </description> - </method> - <method name="get_slide_count" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the number of times the body collided and changed direction during the last call to [method move_and_slide] or [method move_and_slide_with_snap]. - </description> - </method> - <method name="is_on_ceiling" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="is_on_floor" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="is_on_wall" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="move_and_collide"> - <return type="KinematicCollision2D"> - </return> - <argument index="0" name="rel_vec" type="Vector2"> - </argument> - <argument index="1" name="infinite_inertia" type="bool" default="true"> - </argument> - <argument index="2" name="exclude_raycast_shapes" type="bool" default="true"> - </argument> - <argument index="3" name="test_only" type="bool" default="false"> - </argument> - <description> - Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision. - If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given. - </description> - </method> - <method name="move_and_slide"> - <return type="Vector2"> - </return> - <argument index="0" name="linear_velocity" type="Vector2"> - </argument> - <argument index="1" name="up_direction" type="Vector2" default="Vector2( 0, 0 )"> - </argument> - <argument index="2" name="stop_on_slope" type="bool" default="false"> - </argument> - <argument index="3" name="max_slides" type="int" default="4"> - </argument> - <argument index="4" name="floor_max_angle" type="float" default="0.785398"> - </argument> - <argument index="5" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [KinematicBody2D] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. - This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. - [code]linear_velocity[/code] is the velocity vector in pixels per second. Unlike in [method move_and_collide], you should [i]not[/i] multiply it by [code]delta[/code] — the physics engine handles applying the velocity. - [code]up_direction[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games. - If [code]stop_on_slope[/code] is [code]true[/code], body will not slide on slopes when you include gravity in [code]linear_velocity[/code] and the body is standing still. - If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops. - [code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees. - If [code]infinite_inertia[/code] is [code]true[/code], body will be able to push [RigidBody2D] nodes, but it won't also detect any collisions with them. If [code]false[/code], it will interact with [RigidBody2D] nodes like with [StaticBody2D]. - Returns the [code]linear_velocity[/code] vector, rotated and/or scaled if a slide collision occurred. To get detailed information about collisions that occurred, use [method get_slide_collision]. - </description> - </method> - <method name="move_and_slide_with_snap"> - <return type="Vector2"> - </return> - <argument index="0" name="linear_velocity" type="Vector2"> - </argument> - <argument index="1" name="snap" type="Vector2"> - </argument> - <argument index="2" name="up_direction" type="Vector2" default="Vector2( 0, 0 )"> - </argument> - <argument index="3" name="stop_on_slope" type="bool" default="false"> - </argument> - <argument index="4" name="max_slides" type="int" default="4"> - </argument> - <argument index="5" name="floor_max_angle" type="float" default="0.785398"> - </argument> - <argument index="6" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Moves the body while keeping it attached to slopes. Similar to [method move_and_slide]. - As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting [code]snap[/code] to [code](0, 0)[/code] or by using [method move_and_slide] instead. - </description> - </method> - <method name="test_move"> - <return type="bool"> - </return> - <argument index="0" name="from" type="Transform2D"> - </argument> - <argument index="1" name="rel_vec" type="Vector2"> - </argument> - <argument index="2" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. - </description> - </method> - </methods> - <members> - <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.08"> - Extra margin used for collision recovery in motion functions (see [method move_and_collide], [method move_and_slide], [method move_and_slide_with_snap]). - If the body is at least this close to another body, it will consider them to be colliding and will be pushed away before performing the actual motion. - A higher value means it's more flexible for detecting collision, which helps with consistently detecting walls and floors. - A lower value forces the collision algorithm to use more exact detection, so it can be used in cases that specifically require precision, e.g at very low scale to avoid visible jittering, or for stability with a stack of kinematic bodies. - </member> - <member name="motion/sync_to_physics" type="bool" setter="set_sync_to_physics" getter="is_sync_to_physics_enabled" default="false"> - If [code]true[/code], the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms. Do [b]not[/b] use together with [method move_and_slide] or [method move_and_collide] functions. - </member> - </members> - <constants> - </constants> -</class> diff --git a/doc/classes/KinematicBody3D.xml b/doc/classes/KinematicBody3D.xml deleted file mode 100644 index efd3f58f88..0000000000 --- a/doc/classes/KinematicBody3D.xml +++ /dev/null @@ -1,188 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicBody3D" inherits="PhysicsBody3D" version="4.0"> - <brief_description> - Kinematic body 3D node. - </brief_description> - <description> - Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses: - [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). - [b]Kinematic characters:[/b] KinematicBody3D also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but don't require advanced physics. - </description> - <tutorials> - <link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link> - <link title="3D Kinematic Character Demo">https://godotengine.org/asset-library/asset/126</link> - <link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link> - <link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link> - <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> - </tutorials> - <methods> - <method name="get_axis_lock" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis"> - </argument> - <description> - Returns [code]true[/code] if the specified [code]axis[/code] is locked. See also [member axis_lock_motion_x], [member axis_lock_motion_y] and [member axis_lock_motion_z]. - </description> - </method> - <method name="get_floor_normal" qualifiers="const"> - <return type="Vector3"> - </return> - <description> - Returns the surface normal of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code]. - </description> - </method> - <method name="get_floor_velocity" qualifiers="const"> - <return type="Vector3"> - </return> - <description> - Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code]. - </description> - </method> - <method name="get_slide_collision"> - <return type="KinematicCollision3D"> - </return> - <argument index="0" name="slide_idx" type="int"> - </argument> - <description> - Returns a [KinematicCollision3D], which contains information about a collision that occurred during the last call to [method move_and_slide] or [method move_and_slide_with_snap]. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). - </description> - </method> - <method name="get_slide_count" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the number of times the body collided and changed direction during the last call to [method move_and_slide] or [method move_and_slide_with_snap]. - </description> - </method> - <method name="is_on_ceiling" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="is_on_floor" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="is_on_wall" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide] or [method move_and_slide_with_snap]. Otherwise, returns [code]false[/code]. - </description> - </method> - <method name="move_and_collide"> - <return type="KinematicCollision3D"> - </return> - <argument index="0" name="rel_vec" type="Vector3"> - </argument> - <argument index="1" name="infinite_inertia" type="bool" default="true"> - </argument> - <argument index="2" name="exclude_raycast_shapes" type="bool" default="true"> - </argument> - <argument index="3" name="test_only" type="bool" default="false"> - </argument> - <description> - Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision. - If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given. - </description> - </method> - <method name="move_and_slide"> - <return type="Vector3"> - </return> - <argument index="0" name="linear_velocity" type="Vector3"> - </argument> - <argument index="1" name="up_direction" type="Vector3" default="Vector3( 0, 0, 0 )"> - </argument> - <argument index="2" name="stop_on_slope" type="bool" default="false"> - </argument> - <argument index="3" name="max_slides" type="int" default="4"> - </argument> - <argument index="4" name="floor_max_angle" type="float" default="0.785398"> - </argument> - <argument index="5" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [KinematicBody3D] or [RigidBody3D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. - This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. - [code]linear_velocity[/code] is the velocity vector (typically meters per second). Unlike in [method move_and_collide], you should [i]not[/i] multiply it by [code]delta[/code] — the physics engine handles applying the velocity. - [code]up_direction[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector3(0, 0, 0)[/code], everything is considered a wall. - If [code]stop_on_slope[/code] is [code]true[/code], body will not slide on slopes when you include gravity in [code]linear_velocity[/code] and the body is standing still. - If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops. - [code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees. - If [code]infinite_inertia[/code] is [code]true[/code], body will be able to push [RigidBody3D] nodes, but it won't also detect any collisions with them. If [code]false[/code], it will interact with [RigidBody3D] nodes like with [StaticBody3D]. - Returns the [code]linear_velocity[/code] vector, rotated and/or scaled if a slide collision occurred. To get detailed information about collisions that occurred, use [method get_slide_collision]. - </description> - </method> - <method name="move_and_slide_with_snap"> - <return type="Vector3"> - </return> - <argument index="0" name="linear_velocity" type="Vector3"> - </argument> - <argument index="1" name="snap" type="Vector3"> - </argument> - <argument index="2" name="up_direction" type="Vector3" default="Vector3( 0, 0, 0 )"> - </argument> - <argument index="3" name="stop_on_slope" type="bool" default="false"> - </argument> - <argument index="4" name="max_slides" type="int" default="4"> - </argument> - <argument index="5" name="floor_max_angle" type="float" default="0.785398"> - </argument> - <argument index="6" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Moves the body while keeping it attached to slopes. Similar to [method move_and_slide]. - As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting [code]snap[/code] to [code](0, 0, 0)[/code] or by using [method move_and_slide] instead. - </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> - Locks or unlocks the specified [code]axis[/code] depending on the value of [code]lock[/code]. See also [member axis_lock_motion_x], [member axis_lock_motion_y] and [member axis_lock_motion_z]. - </description> - </method> - <method name="test_move"> - <return type="bool"> - </return> - <argument index="0" name="from" type="Transform"> - </argument> - <argument index="1" name="rel_vec" type="Vector3"> - </argument> - <argument index="2" name="infinite_inertia" type="bool" default="true"> - </argument> - <description> - Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. - </description> - </method> - </methods> - <members> - <member name="axis_lock_motion_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's X axis movement. - </member> - <member name="axis_lock_motion_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's Y axis movement. - </member> - <member name="axis_lock_motion_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's Z axis movement. - </member> - <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.001"> - Extra margin used for collision recovery in motion functions (see [method move_and_collide], [method move_and_slide], [method move_and_slide_with_snap]). - If the body is at least this close to another body, it will consider them to be colliding and will be pushed away before performing the actual motion. - A higher value means it's more flexible for detecting collision, which helps with consistently detecting walls and floors. - A lower value forces the collision algorithm to use more exact detection, so it can be used in cases that specifically require precision, e.g at very low scale to avoid visible jittering, or for stability with a stack of kinematic bodies. - </member> - </members> - <constants> - </constants> -</class> diff --git a/doc/classes/KinematicCollision2D.xml b/doc/classes/KinematicCollision2D.xml index ec6e16e25a..8748f89618 100644 --- a/doc/classes/KinematicCollision2D.xml +++ b/doc/classes/KinematicCollision2D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="KinematicCollision2D" inherits="Reference" version="4.0"> <brief_description> - Collision data for [KinematicBody2D] collisions. + Collision data for [method PhysicsBody2D.move_and_collide] collisions. </brief_description> <description> - Contains collision data for [KinematicBody2D] collisions. When a [KinematicBody2D] is moved using [method KinematicBody2D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a KinematicCollision2D object is returned. + Contains collision data for [method PhysicsBody2D.move_and_collide] collisions. When a [PhysicsBody2D] is moved using [method PhysicsBody2D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision2D] object is returned. This object contains information about the collision, including the colliding object, the remaining motion, and the collision position. This information can be used to calculate a collision response. </description> <tutorials> diff --git a/doc/classes/KinematicCollision3D.xml b/doc/classes/KinematicCollision3D.xml index f3248a9ca1..8eac15ebf4 100644 --- a/doc/classes/KinematicCollision3D.xml +++ b/doc/classes/KinematicCollision3D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="KinematicCollision3D" inherits="Reference" version="4.0"> <brief_description> - Collision data for [KinematicBody3D] collisions. + Collision data for [method PhysicsBody3D.move_and_collide] collisions. </brief_description> <description> - Contains collision data for [KinematicBody3D] collisions. When a [KinematicBody3D] is moved using [method KinematicBody3D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a KinematicCollision3D object is returned. + Contains collision data for [method PhysicsBody3D.move_and_collide] collisions. When a [PhysicsBody3D] is moved using [method PhysicsBody3D.move_and_collide], it stops if it detects a collision with another body. If a collision is detected, a [KinematicCollision3D] object is returned. This object contains information about the collision, including the colliding object, the remaining motion, and the collision position. This information can be used to calculate a collision response. </description> <tutorials> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 6bae612c9f..42b9ed8ab4 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -52,7 +52,7 @@ The light's strength multiplier (this is not a physical unit). For [OmniLight3D] and [SpotLight3D], changing this value will only change the light color's intensity, not the light's radius. </member> <member name="light_indirect_energy" type="float" setter="set_param" getter="get_param" default="1.0"> - Secondary multiplier used with indirect light (light bounces). Used with [GIProbe]. + Secondary multiplier used with indirect light (light bounces). Used with [VoxelGI]. </member> <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. diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/LightmapGI.xml index 6fd08fc4e4..d7722a83b0 100644 --- a/doc/classes/BakedLightmap.xml +++ b/doc/classes/LightmapGI.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BakedLightmap" inherits="VisualInstance3D" version="4.0"> +<class name="LightmapGI" inherits="VisualInstance3D" version="4.0"> <brief_description> </brief_description> <description> @@ -21,17 +21,17 @@ </member> <member name="environment_custom_sky" type="Sky" setter="set_environment_custom_sky" getter="get_environment_custom_sky"> </member> - <member name="environment_mode" type="int" setter="set_environment_mode" getter="get_environment_mode" enum="BakedLightmap.EnvironmentMode" default="0"> + <member name="environment_mode" type="int" setter="set_environment_mode" getter="get_environment_mode" enum="LightmapGI.EnvironmentMode" default="0"> </member> - <member name="generate_probes_subdiv" type="int" setter="set_generate_probes" getter="get_generate_probes" enum="BakedLightmap.GenerateProbes" default="0"> + <member name="generate_probes_subdiv" type="int" setter="set_generate_probes" getter="get_generate_probes" enum="LightmapGI.GenerateProbes" default="0"> </member> <member name="interior" type="bool" setter="set_interior" getter="is_interior" default="false"> </member> - <member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data"> + <member name="light_data" type="LightmapGIData" setter="set_light_data" getter="get_light_data"> </member> <member name="max_texture_size" type="int" setter="set_max_texture_size" getter="get_max_texture_size" default="16384"> </member> - <member name="quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality" default="1"> + <member name="quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="LightmapGI.BakeQuality" default="1"> </member> <member name="use_denoiser" type="bool" setter="set_use_denoiser" getter="is_using_denoiser" default="true"> </member> diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/LightmapGIData.xml index 904555c48e..3a37c6dcb7 100644 --- a/doc/classes/BakedLightmapData.xml +++ b/doc/classes/LightmapGIData.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BakedLightmapData" inherits="Resource" version="4.0"> +<class name="LightmapGIData" inherits="Resource" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Listener3D.xml b/doc/classes/Listener3D.xml index 998ea757ff..b2fcbe534d 100644 --- a/doc/classes/Listener3D.xml +++ b/doc/classes/Listener3D.xml @@ -18,10 +18,10 @@ </description> </method> <method name="get_listener_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> - Returns the listener's global orthonormalized [Transform]. + Returns the listener's global orthonormalized [Transform3D]. </description> </method> <method name="is_current" qualifiers="const"> diff --git a/doc/classes/MeshLibrary.xml b/doc/classes/MeshLibrary.xml index ad8bd6991d..b33bcc89e3 100644 --- a/doc/classes/MeshLibrary.xml +++ b/doc/classes/MeshLibrary.xml @@ -72,7 +72,7 @@ </description> </method> <method name="get_item_navmesh_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="id" type="int"> </argument> @@ -96,7 +96,7 @@ </argument> <description> Returns an item's collision shapes. - The array consists of each [Shape3D] followed by its [Transform]. + The array consists of each [Shape3D] followed by its [Transform3D]. </description> </method> <method name="get_last_unused_item_id" qualifiers="const"> @@ -154,7 +154,7 @@ </return> <argument index="0" name="id" type="int"> </argument> - <argument index="1" name="navmesh" type="Transform"> + <argument index="1" name="navmesh" type="Transform3D"> </argument> <description> Sets the transform to apply to the item's navigation mesh. @@ -180,7 +180,7 @@ </argument> <description> Sets an item's collision shapes. - The array should consist of [Shape3D] objects, each followed by a [Transform] that will be applied to it. For shapes that should not have a transform, use [constant Transform.IDENTITY]. + The array should consist of [Shape3D] objects, each followed by a [Transform3D] that will be applied to it. For shapes that should not have a transform, use [constant Transform3D.IDENTITY]. </description> </method> </methods> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 2adebdb306..02628f4960 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -40,12 +40,12 @@ </description> </method> <method name="get_instance_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="instance" type="int"> </argument> <description> - Returns the [Transform] of a specific instance. + Returns the [Transform3D] of a specific instance. </description> </method> <method name="get_instance_transform_2d" qualifiers="const"> @@ -86,10 +86,10 @@ </return> <argument index="0" name="instance" type="int"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> - Sets the [Transform] for a specific instance. + Sets the [Transform3D] for a specific instance. </description> </method> <method name="set_instance_transform_2d"> diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index c168695d61..b2be92dbbd 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -135,16 +135,16 @@ </signals> <constants> <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. + Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. </constant> <constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets. + Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets. </constant> <constant name="RPC_MODE_MASTER" value="2" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network puppets, see [method Node.set_network_master]. + Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network puppets, see [method Node.set_network_master]. </constant> <constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode"> - Used with [method Node.rpc_config] or [method Node.rset_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master]. + Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master]. </constant> <constant name="RPC_MODE_REMOTESYNC" value="4" enum="RPCMode"> Behave like [constant RPC_MODE_REMOTE] but also make the call or property change locally. Analogous to the [code]remotesync[/code] keyword. diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index b098a7fc20..ef9efcb99c 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -413,7 +413,7 @@ </return> <argument index="0" name="region" type="RID"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> Sets the global transformation for the region. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 523f3a0c17..1300351e47 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -649,7 +649,7 @@ <argument index="0" name="method" type="StringName"> </argument> <description> - Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. See also [method rset] and [method rset_config] for properties. Returns an empty [Variant]. + Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns an empty [Variant]. [b]Note:[/b] You can only safely use RPCs on clients after you received the [code]connected_to_server[/code] signal from the [SceneTree]. You also need to keep track of the connection state, either by the [SceneTree] signals like [code]server_disconnected[/code] or by checking [code]SceneTree.network_peer.get_connection_status() == CONNECTION_CONNECTED[/code]. </description> </method> @@ -658,33 +658,17 @@ </return> <argument index="0" name="method" type="StringName"> </argument> - <argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> + <argument index="1" name="rpc_mode" type="int" enum="MultiplayerAPI.RPCMode"> </argument> - <description> - Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, methods are not exposed to networking (and RPCs). See also [method rset] and [method rset_config] for properties. - </description> - </method> - <method name="rpc_id" qualifiers="vararg"> - <return type="Variant"> - </return> - <argument index="0" name="peer_id" type="int"> + <argument index="2" name="transfer_mode" type="int" enum="NetworkedMultiplayerPeer.TransferMode" default="2"> </argument> - <argument index="1" name="method" type="StringName"> - </argument> - <description> - Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant]. - </description> - </method> - <method name="rpc_unreliable" qualifiers="vararg"> - <return type="Variant"> - </return> - <argument index="0" name="method" type="StringName"> + <argument index="3" name="channel" type="int" default="0"> </argument> <description> - Sends a [method rpc] using an unreliable protocol. Returns an empty [Variant]. + Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum MultiplayerAPI.RPCMode] and [enum NetworkedMultiplayerPeer.TransferMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, methods are not exposed to networking (and RPCs). </description> </method> - <method name="rpc_unreliable_id" qualifiers="vararg"> + <method name="rpc_id" qualifiers="vararg"> <return type="Variant"> </return> <argument index="0" name="peer_id" type="int"> @@ -692,66 +676,7 @@ <argument index="1" name="method" type="StringName"> </argument> <description> - Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] using an unreliable protocol (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant]. - </description> - </method> - <method name="rset"> - <return type="void"> - </return> - <argument index="0" name="property" type="StringName"> - </argument> - <argument index="1" name="value" type="Variant"> - </argument> - <description> - Remotely changes a property's value on other peers (and locally). Behaviour depends on the RPC configuration for the given property, see [method rset_config]. See also [method rpc] for RPCs for methods, most information applies to this method as well. - </description> - </method> - <method name="rset_config"> - <return type="int"> - </return> - <argument index="0" name="property" type="StringName"> - </argument> - <argument index="1" name="mode" type="int" enum="MultiplayerAPI.RPCMode"> - </argument> - <description> - Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum MultiplayerAPI.RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, properties are not exposed to networking (and RPCs). See also [method rpc] and [method rpc_config] for methods. - </description> - </method> - <method name="rset_id"> - <return type="void"> - </return> - <argument index="0" name="peer_id" type="int"> - </argument> - <argument index="1" name="property" type="StringName"> - </argument> - <argument index="2" name="value" type="Variant"> - </argument> - <description> - Remotely changes the property's value on a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). - </description> - </method> - <method name="rset_unreliable"> - <return type="void"> - </return> - <argument index="0" name="property" type="StringName"> - </argument> - <argument index="1" name="value" type="Variant"> - </argument> - <description> - Remotely changes the property's value on other peers (and locally) using an unreliable protocol. - </description> - </method> - <method name="rset_unreliable_id"> - <return type="void"> - </return> - <argument index="0" name="peer_id" type="int"> - </argument> - <argument index="1" name="property" type="StringName"> - </argument> - <argument index="2" name="value" type="Variant"> - </argument> - <description> - Remotely changes property's value on a specific peer identified by [code]peer_id[/code] using an unreliable protocol (see [method NetworkedMultiplayerPeer.set_target_peer]). + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] (see [method NetworkedMultiplayerPeer.set_target_peer]). Returns an empty [Variant]. </description> </method> <method name="set_display_folded"> @@ -969,6 +894,12 @@ <constant name="NOTIFICATION_POST_ENTER_TREE" value="27"> Notification received when the node is ready, just before [constant NOTIFICATION_READY] is received. Unlike the latter, it's sent every time the node enters tree, instead of only once. </constant> + <constant name="NOTIFICATION_EDITOR_PRE_SAVE" value="9001"> + Notification received right before the scene with the node is saved in the editor. This notification is only sent in the Godot editor and will not occur in exported projects. + </constant> + <constant name="NOTIFICATION_EDITOR_POST_SAVE" value="9002"> + Notification received right after the scene with the node is saved in the editor. This notification is only sent in the Godot editor and will not occur in exported projects. + </constant> <constant name="NOTIFICATION_WM_MOUSE_ENTER" value="1002"> Notification received from the OS when the mouse enters the game window. Implemented on desktop and web platforms. diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml index 988fb72267..8ca945418c 100644 --- a/doc/classes/Node2D.xml +++ b/doc/classes/Node2D.xml @@ -150,6 +150,10 @@ <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform"> Local [Transform2D]. </member> + <member name="y_sort_enabled" type="bool" setter="set_y_sort_enabled" getter="is_y_sort_enabled" default="false"> + If [code]true[/code], child nodes with the lowest Y position are drawn before those with a higher Y position. If [code]false[/code], Y-sorting is disabled. Y-sorting only affects children that inherit from [CanvasItem]. + You can nest nodes with Y-sorting. Child Y-sorted nodes are sorted in the same space as the parent Y-sort. This feature allows you to organize a scene better or divide it into multiple ones without changing your scene tree. + </member> <member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative" default="true"> If [code]true[/code], the node's Z index is relative to its parent's Z index. If this node's Z index is 2 and its parent's effective Z index is 3, then this node's effective Z index will be 2 + 3 = 5. </member> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index 5c29c0d48f..a6237708c6 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -4,7 +4,7 @@ Most basic 3D game object, parent of all 3D-related nodes. </brief_description> <description> - Most basic 3D game object, with a 3D [Transform] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. + Most basic 3D game object, with a 3D [Transform3D] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system. [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg2rad]. </description> @@ -128,7 +128,7 @@ <return type="void"> </return> <description> - Resets this node's transformations (like scale, skew and taper) preserving its rotation and translation by performing Gram-Schmidt orthonormalization on this node's [Transform]. + Resets this node's transformations (like scale, skew and taper) preserving its rotation and translation by performing Gram-Schmidt orthonormalization on this node's [Transform3D]. </description> </method> <method name="rotate"> @@ -202,7 +202,7 @@ <return type="void"> </return> <description> - Reset all transformations for this node (sets its [Transform] to the identity matrix). + Reset all transformations for this node (sets its [Transform3D] to the identity matrix). </description> </method> <method name="set_ignore_transform_notification"> @@ -288,8 +288,11 @@ <member name="gizmo" type="Node3DGizmo" setter="set_gizmo" getter="get_gizmo"> The [Node3DGizmo] for this node. Used for example in [EditorNode3DGizmo] as custom visualization and editing handles in Editor. </member> - <member name="global_transform" type="Transform" setter="set_global_transform" getter="get_global_transform"> - World3D space (global) [Transform] of this node. + <member name="global_transform" type="Transform3D" setter="set_global_transform" getter="get_global_transform"> + World3D space (global) [Transform3D] of this node. + </member> + <member name="position" type="Vector3" setter="set_position" getter="get_position" default="Vector3( 0, 0, 0 )"> + Local position or translation of this node relative to the parent. This is equivalent to [code]transform.origin[/code]. </member> <member name="rotation" type="Vector3" setter="set_rotation" getter="get_rotation"> Rotation part of the local transformation in radians, specified in terms of YXZ-Euler angles in the format (X angle, Y angle, Z angle). @@ -304,11 +307,8 @@ <member name="top_level" type="bool" setter="set_as_top_level" getter="is_set_as_top_level" default="false"> If [code]true[/code], the node will not inherit its transformations from its parent. Node transformations are only in global space. </member> - <member name="transform" type="Transform" setter="set_transform" getter="get_transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> - Local space [Transform] of this node, with respect to the parent node. - </member> - <member name="translation" type="Vector3" setter="set_translation" getter="get_translation" default="Vector3( 0, 0, 0 )"> - Local translation of this node. + <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + Local space [Transform3D] of this node, with respect to the parent node. </member> <member name="visible" type="bool" setter="set_visible" getter="is_visible" default="true"> If [code]true[/code], this node is drawn. The node is only visible if all of its antecedents are visible as well (in other words, [method is_visible_in_tree] must return [code]true[/code]). diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 85d41d7519..00ded39082 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -106,7 +106,7 @@ <method name="operator *" qualifiers="operator"> <return type="PackedVector3Array"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> diff --git a/doc/classes/PhysicalBone2D.xml b/doc/classes/PhysicalBone2D.xml new file mode 100644 index 0000000000..cea75bad52 --- /dev/null +++ b/doc/classes/PhysicalBone2D.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PhysicalBone2D" inherits="RigidBody2D" version="4.0"> + <brief_description> + A 2D node that can be used for physically aware bones in 2D. + </brief_description> + <description> + The [code]PhysicalBone2D[/code] node is a [RigidBody2D]-based node that can be used to make [Bone2D] nodes in a [Skeleton2D] react to physics. This node is very similar to the [PhysicalBone3D] node, just for 2D instead of 3D. + [b]Note:[/b] To have the Bone2D nodes visually follow the [code]PhysicalBone2D[/code] node, use a [SkeletonModification2DPhysicalBones] modification on the [Skeleton2D] node with the [Bone2D] nodes. + [b]Note:[/b] The PhysicalBone2D node does not automatically create a [Joint2D] node to keep [code]PhysicalBone2D[/code] nodes together. You will need to create these manually. For most cases, you want to use a [PinJoint2D] node. The [code]PhysicalBone2D[/code] node can automatically configure the [Joint2D] node once it's been created as a child node. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_joint" qualifiers="const"> + <return type="Joint2D"> + </return> + <description> + Returns the first [Joint2D] child node, if one exists. This is mainly a helper function to make it easier to get the [Joint2D] that the [code]PhysicalBone2D[/code] is autoconfiguring. + </description> + </method> + <method name="is_simulating_physics" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns a boolean that indicates whether the [code]PhysicalBone2D[/code] node is running and simulating using the Godot 2D physics engine. When [code]true[/code], the PhysicalBone2D node is using physics. + </description> + </method> + </methods> + <members> + <member name="auto_configure_joint" type="bool" setter="set_auto_configure_joint" getter="get_auto_configure_joint" default="true"> + If [code]true[/code], the [code]PhysicalBone2D[/code] node will automatically configure the first [Joint2D] child node. The automatic configuration is limited to setting up the node properties and positioning the [Joint2D]. + </member> + <member name="bone2d_index" type="int" setter="set_bone2d_index" getter="get_bone2d_index" default="-1"> + The index of the [Bone2D] node that this [code]PhysicalBone2D[/code] node is supposed to be simulating. + </member> + <member name="bone2d_nodepath" type="NodePath" setter="set_bone2d_nodepath" getter="get_bone2d_nodepath" default="NodePath("")"> + The [NodePath] to the [Bone2D] node that this [code]PhysicalBone2D[/code] node is supposed to be simulating. + </member> + <member name="follow_bone_when_simulating" type="bool" setter="set_follow_bone_when_simulating" getter="get_follow_bone_when_simulating" default="false"> + If [code]true[/code], the [code]PhysicalBone2D[/code] will keep the transform of the bone it is bound to when simulating physics. + </member> + <member name="simulate_physics" type="bool" setter="set_simulate_physics" getter="get_simulate_physics" default="false"> + If [code]true[/code], the [code]PhysicalBone2D[/code] will start simulating using physics. If [code]false[/code], the [code]PhysicalBone2D[/code] will follow the transform of the [Bone2D] node. + [b]Note:[/b] To have the Bone2D nodes visually follow the [code]PhysicalBone2D[/code] node, use a [SkeletonModification2DPhysicalBones] modification on the [Skeleton2D] node with the [Bone2D] nodes. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index 38d9f722b1..5d15590a3f 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -25,14 +25,6 @@ <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> @@ -51,40 +43,12 @@ <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"> Damps the body's rotation if greater than [code]0[/code]. </member> - <member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the X axis. - </member> - <member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the Y axis. - </member> - <member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the Z axis. - </member> - <member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the X axis. - </member> - <member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the Y axis. - </member> - <member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the Z axis. - </member> - <member name="body_offset" type="Transform" setter="set_body_offset" getter="get_body_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <member name="body_offset" type="Transform3D" setter="set_body_offset" getter="get_body_offset" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> Sets the body's transform. </member> <member name="bounce" type="float" setter="set_bounce" getter="get_bounce" default="0.0"> @@ -99,7 +63,7 @@ <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0"> This is multiplied by the global 3D gravity setting found in [b]Project > Project Settings > Physics > 3d[/b] to produce the body's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object. </member> - <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 )"> + <member name="joint_offset" type="Transform3D" setter="set_joint_offset" getter="get_joint_offset" default="Transform3D( 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"> diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml index e43d3bb762..654b0fb668 100644 --- a/doc/classes/PhysicsBody2D.xml +++ b/doc/classes/PhysicsBody2D.xml @@ -26,6 +26,25 @@ Returns an array of nodes that were added as collision exceptions for this body. </description> </method> + <method name="move_and_collide"> + <return type="KinematicCollision2D"> + </return> + <argument index="0" name="rel_vec" type="Vector2"> + </argument> + <argument index="1" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="2" name="exclude_raycast_shapes" type="bool" default="true"> + </argument> + <argument index="3" name="test_only" type="bool" default="false"> + </argument> + <argument index="4" name="safe_margin" type="float" default="0.08"> + </argument> + <description> + Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision. + If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given. + [code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details). + </description> + </method> <method name="remove_collision_exception_with"> <return type="void"> </return> @@ -35,6 +54,27 @@ Removes a body from the list of bodies that this body can't collide with. </description> </method> + <method name="test_move"> + <return type="bool"> + </return> + <argument index="0" name="from" type="Transform2D"> + </argument> + <argument index="1" name="rel_vec" type="Vector2"> + </argument> + <argument index="2" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="3" name="exclude_raycast_shapes" type="bool" default="true"> + </argument> + <argument index="4" name="collision" type="KinematicCollision2D" default="null"> + </argument> + <argument index="5" name="safe_margin" type="float" default="0.08"> + </argument> + <description> + Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. + [code]collision[/code] is an optional object of type [KinematicCollision2D], which contains additional information about the collision (should there be one). + [code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details). + </description> + </method> </methods> <members> <member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable" override="true" default="false" /> diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml index b320d37d23..1ec38000be 100644 --- a/doc/classes/PhysicsBody3D.xml +++ b/doc/classes/PhysicsBody3D.xml @@ -19,6 +19,15 @@ Adds a body to the list of bodies that this body can't collide with. </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> + Returns [code]true[/code] if the specified linear or rotational [code]axis[/code] is locked. + </description> + </method> <method name="get_collision_exceptions"> <return type="PhysicsBody3D[]"> </return> @@ -26,6 +35,25 @@ Returns an array of nodes that were added as collision exceptions for this body. </description> </method> + <method name="move_and_collide"> + <return type="KinematicCollision3D"> + </return> + <argument index="0" name="rel_vec" type="Vector3"> + </argument> + <argument index="1" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="2" name="exclude_raycast_shapes" type="bool" default="true"> + </argument> + <argument index="3" name="test_only" type="bool" default="false"> + </argument> + <argument index="4" name="safe_margin" type="float" default="0.001"> + </argument> + <description> + Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision. + If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given. + [code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details). + </description> + </method> <method name="remove_collision_exception_with"> <return type="void"> </return> @@ -35,7 +63,59 @@ Removes a body from the list of bodies that this body can't collide with. </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> + Locks or unlocks the specified linear or rotational [code]axis[/code] depending on the value of [code]lock[/code]. + </description> + </method> + <method name="test_move"> + <return type="bool"> + </return> + <argument index="0" name="from" type="Transform3D"> + </argument> + <argument index="1" name="rel_vec" type="Vector3"> + </argument> + <argument index="2" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="3" name="exclude_raycast_shapes" type="bool" default="true"> + </argument> + <argument index="4" name="collision" type="KinematicCollision3D" default="null"> + </argument> + <argument index="5" name="safe_margin" type="float" default="0.001"> + </argument> + <description> + Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. + [code]collision[/code] is an optional object of type [KinematicCollision3D], which contains additional information about the collision (should there be one). + [code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details). + </description> + </method> </methods> + <members> + <member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the X axis. + </member> + <member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the Y axis. + </member> + <member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the Z axis. + </member> + <member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's linear movement in the X axis. + </member> + <member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's linear movement in the Y axis. + </member> + <member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's linear movement in the Z axis. + </member> + </members> <constants> </constants> </class> diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml index dfc0ab909a..66ff16a3ce 100644 --- a/doc/classes/PhysicsDirectBodyState2D.xml +++ b/doc/classes/PhysicsDirectBodyState2D.xml @@ -4,7 +4,7 @@ Direct access object to a physics body in the [PhysicsServer2D]. </brief_description> <description> - Provides direct access to a physics body in the [PhysicsServer2D], allowing safe changes to physics properties. This object is passed via the direct state callback of rigid/character bodies, and is intended for changing the direct state of that body. See [method RigidBody2D._integrate_forces]. + Provides direct access to a physics body in the [PhysicsServer2D], allowing safe changes to physics properties. This object is passed via the direct state callback of dynamic bodies, and is intended for changing the direct state of that body. See [method RigidBody2D._integrate_forces]. </description> <tutorials> <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link> diff --git a/doc/classes/PhysicsDirectBodyState3D.xml b/doc/classes/PhysicsDirectBodyState3D.xml index eea681e696..7cb3a56338 100644 --- a/doc/classes/PhysicsDirectBodyState3D.xml +++ b/doc/classes/PhysicsDirectBodyState3D.xml @@ -4,7 +4,7 @@ Direct access object to a physics body in the [PhysicsServer3D]. </brief_description> <description> - Provides direct access to a physics body in the [PhysicsServer3D], allowing safe changes to physics properties. This object is passed via the direct state callback of rigid/character bodies, and is intended for changing the direct state of that body. See [method RigidBody3D._integrate_forces]. + Provides direct access to a physics body in the [PhysicsServer3D], allowing safe changes to physics properties. This object is passed via the direct state callback of dynamic bodies, and is intended for changing the direct state of that body. See [method RigidBody3D._integrate_forces]. </description> <tutorials> </tutorials> @@ -214,7 +214,7 @@ <member name="total_linear_damp" type="float" setter="" getter="get_total_linear_damp"> The rate at which the body stops moving, if there are not any other forces moving it. </member> - <member name="transform" type="Transform" setter="set_transform" getter="get_transform"> + <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform"> The body's transformation matrix. </member> </members> diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index cfa4215fd4..4c2abcb087 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -1207,16 +1207,16 @@ This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </constant> <constant name="BODY_MODE_STATIC" value="0" enum="BodyMode"> - Constant for static bodies. + Constant for static bodies. In this mode, a body can be only moved by user code. </constant> <constant name="BODY_MODE_KINEMATIC" value="1" enum="BodyMode"> - Constant for kinematic bodies. + Constant for kinematic bodies. In this mode, a body can be only moved by user code and collides with other bodies along its path. </constant> - <constant name="BODY_MODE_RIGID" value="2" enum="BodyMode"> - Constant for rigid bodies. + <constant name="BODY_MODE_DYNAMIC" value="2" enum="BodyMode"> + Constant for dynamic bodies. In this mode, a body can be pushed by other bodies and has forces applied. </constant> - <constant name="BODY_MODE_CHARACTER" value="3" enum="BodyMode"> - Constant for rigid bodies in character mode. In this mode, a body can not rotate, and only its linear velocity is affected by physics. + <constant name="BODY_MODE_DYNAMIC_LOCKED" value="3" enum="BodyMode"> + Constant for locked dynamic bodies. In this mode, a body is dynamic but can not rotate, and only its linear velocity is affected by external forces. </constant> <constant name="BODY_PARAM_BOUNCE" value="0" enum="BodyParameter"> Constant to set/get a body's bounce factor. diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index 46de9e5282..2972d5155c 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -16,7 +16,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <argument index="2" name="transform" type="Transform3D" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> <argument index="3" name="disabled" type="bool" default="false"> </argument> @@ -92,7 +92,7 @@ </description> </method> <method name="area_get_shape_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="area" type="RID"> </argument> @@ -121,7 +121,7 @@ </description> </method> <method name="area_get_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="area" type="RID"> </argument> @@ -258,7 +258,7 @@ </argument> <argument index="1" name="shape_idx" type="int"> </argument> - <argument index="2" name="transform" type="Transform"> + <argument index="2" name="transform" type="Transform3D"> </argument> <description> Sets the transform matrix for an area shape. @@ -291,7 +291,7 @@ </return> <argument index="0" name="area" type="RID"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> Sets the transform matrix for an area. @@ -337,7 +337,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <argument index="2" name="transform" type="Transform3D" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> <argument index="3" name="disabled" type="bool" default="false"> </argument> @@ -443,14 +443,6 @@ Returns the [PhysicsDirectBodyState3D] of the body. </description> </method> - <method name="body_get_kinematic_safe_margin" qualifiers="const"> - <return type="float"> - </return> - <argument index="0" name="body" type="RID"> - </argument> - <description> - </description> - </method> <method name="body_get_max_contacts_reported" qualifiers="const"> <return type="int"> </return> @@ -510,7 +502,7 @@ </description> </method> <method name="body_get_shape_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -661,16 +653,6 @@ Sets the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force_integration]). </description> </method> - <method name="body_set_kinematic_safe_margin"> - <return type="void"> - </return> - <argument index="0" name="body" type="RID"> - </argument> - <argument index="1" name="margin" type="float"> - </argument> - <description> - </description> - </method> <method name="body_set_max_contacts_reported"> <return type="void"> </return> @@ -760,7 +742,7 @@ </argument> <argument index="1" name="shape_idx" type="int"> </argument> - <argument index="2" name="transform" type="Transform"> + <argument index="2" name="transform" type="Transform3D"> </argument> <description> Sets the transform matrix for a body shape. @@ -1017,11 +999,11 @@ </argument> <argument index="1" name="body_A" type="RID"> </argument> - <argument index="2" name="local_ref_A" type="Transform"> + <argument index="2" name="local_ref_A" type="Transform3D"> </argument> <argument index="3" name="body_B" type="RID"> </argument> - <argument index="4" name="local_ref_B" type="Transform"> + <argument index="4" name="local_ref_B" type="Transform3D"> </argument> <description> </description> @@ -1033,11 +1015,11 @@ </argument> <argument index="1" name="body_A" type="RID"> </argument> - <argument index="2" name="local_ref_A" type="Transform"> + <argument index="2" name="local_ref_A" type="Transform3D"> </argument> <argument index="3" name="body_B" type="RID"> </argument> - <argument index="4" name="local_ref_B" type="Transform"> + <argument index="4" name="local_ref_B" type="Transform3D"> </argument> <description> </description> @@ -1049,11 +1031,11 @@ </argument> <argument index="1" name="body_A" type="RID"> </argument> - <argument index="2" name="hinge_A" type="Transform"> + <argument index="2" name="hinge_A" type="Transform3D"> </argument> <argument index="3" name="body_B" type="RID"> </argument> - <argument index="4" name="hinge_B" type="Transform"> + <argument index="4" name="hinge_B" type="Transform3D"> </argument> <description> </description> @@ -1081,11 +1063,11 @@ </argument> <argument index="1" name="body_A" type="RID"> </argument> - <argument index="2" name="local_ref_A" type="Transform"> + <argument index="2" name="local_ref_A" type="Transform3D"> </argument> <argument index="3" name="body_B" type="RID"> </argument> - <argument index="4" name="local_ref_B" type="Transform"> + <argument index="4" name="local_ref_B" type="Transform3D"> </argument> <description> </description> @@ -1595,16 +1577,16 @@ This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one. </constant> <constant name="BODY_MODE_STATIC" value="0" enum="BodyMode"> - Constant for static bodies. + Constant for static bodies. In this mode, a body can be only moved by user code. </constant> <constant name="BODY_MODE_KINEMATIC" value="1" enum="BodyMode"> - Constant for kinematic bodies. + Constant for kinematic bodies. In this mode, a body can be only moved by user code and collides with other bodies along its path. </constant> - <constant name="BODY_MODE_RIGID" value="2" enum="BodyMode"> - Constant for rigid bodies. + <constant name="BODY_MODE_DYNAMIC" value="2" enum="BodyMode"> + Constant for dynamic bodies. In this mode, a body can be pushed by other bodies and has forces applied. </constant> - <constant name="BODY_MODE_CHARACTER" value="3" enum="BodyMode"> - Constant for rigid bodies in character mode. In this mode, a body can not rotate, and only its linear velocity is affected by physics. + <constant name="BODY_MODE_DYNAMIC_LOCKED" value="3" enum="BodyMode"> + Constant for locked dynamic bodies. In this mode, a body is dynamic but can not rotate, and only its linear velocity is affected by external forces. </constant> <constant name="BODY_PARAM_BOUNCE" value="0" enum="BodyParameter"> Constant to set/get a body's bounce factor. diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml index 4b43ea66fc..79bc29057f 100644 --- a/doc/classes/PhysicsShapeQueryParameters3D.xml +++ b/doc/classes/PhysicsShapeQueryParameters3D.xml @@ -60,7 +60,7 @@ [/csharp] [/codeblocks] </member> - <member name="transform" type="Transform" setter="set_transform" getter="get_transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> The queried shape's transform matrix. </member> </members> diff --git a/doc/classes/PinJoint2D.xml b/doc/classes/PinJoint2D.xml index 42155a7f25..ed45149cdf 100644 --- a/doc/classes/PinJoint2D.xml +++ b/doc/classes/PinJoint2D.xml @@ -4,7 +4,7 @@ Pin joint for 2D shapes. </brief_description> <description> - Pin joint for 2D rigid bodies. It pins two bodies (rigid or static) together. + Pin joint for 2D rigid bodies. It pins two bodies (dynamic or static) together. </description> <tutorials> </tutorials> diff --git a/doc/classes/PinJoint3D.xml b/doc/classes/PinJoint3D.xml index 267ea38873..37a85e497f 100644 --- a/doc/classes/PinJoint3D.xml +++ b/doc/classes/PinJoint3D.xml @@ -4,7 +4,7 @@ Pin joint for 3D PhysicsBodies. </brief_description> <description> - Pin joint for 3D rigid bodies. It pins 2 bodies (rigid or static) together. See also [Generic6DOFJoint3D]. + Pin joint for 3D rigid bodies. It pins 2 bodies (dynamic or static) together. See also [Generic6DOFJoint3D]. </description> <tutorials> </tutorials> diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 8b73bcb9c1..3892633654 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -31,7 +31,7 @@ </methods> <members> <member name="custom_aabb" type="AABB" setter="set_custom_aabb" getter="get_custom_aabb" default="AABB( 0, 0, 0, 0, 0, 0 )"> - Overrides the [AABB] with one defined by user for use with frustum culling. Especially useful to avoid unexpected culling when using a shader to offset vertices. + Overrides the [AABB] with one defined by user for use with frustum culling. Especially useful to avoid unexpected culling when using a shader to offset vertices. </member> <member name="flip_faces" type="bool" setter="set_flip_faces" getter="get_flip_faces" default="false"> If set, the order of the vertices in each triangle are reversed resulting in the backside of the mesh being drawn. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index a200858a3c..efd4793b4c 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -551,7 +551,7 @@ prime-run %command% [/codeblock] </member> - <member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( "gd", "shader" )"> + <member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( "gd", "gdshader" )"> Text-based file extensions to include in the script editor's "Find in Files" feature. You can add e.g. [code]tscn[/code] if you wish to also parse your scene files, especially if you use built-in scripts which are serialized in the scene files. </member> <member name="editor/script/templates_search_path" type="String" setter="" getter="" default=""res://script_templates""> @@ -1139,8 +1139,6 @@ <member name="layer_names/3d_render/layer_9" type="String" setter="" getter="" default=""""> Optional name for the 3D render layer 9. If left empty, the layer will display as "Layer 9". </member> - <member name="memory/limits/command_queue/multithreading_queue_size_kb" type="int" setter="" getter="" default="256"> - </member> <member name="memory/limits/message_queue/max_size_kb" type="int" setter="" getter="" default="4096"> Godot uses a message queue to defer some function calls. If you run out of space on it (you will see an error), you can increase the size here. </member> @@ -1421,18 +1419,16 @@ </member> <member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false"> </member> - <member name="rendering/global_illumination/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/global_illumination/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/global_illumination/sdfgi/frames_to_converge" type="int" setter="" getter="" default="4"> </member> <member name="rendering/global_illumination/sdfgi/frames_to_update_lights" type="int" setter="" getter="" default="2"> </member> <member name="rendering/global_illumination/sdfgi/probe_ray_count" type="int" setter="" getter="" default="1"> </member> + <member name="rendering/global_illumination/voxel_gi/anisotropic" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/global_illumination/voxel_gi/quality" type="int" setter="" getter="" default="1"> + </member> <member name="rendering/lightmapping/bake_performance/max_rays_per_pass" type="int" setter="" getter="" default="32"> </member> <member name="rendering/lightmapping/bake_performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64"> diff --git a/doc/classes/Quat.xml b/doc/classes/Quaternion.xml index 1c0a3e37c0..678fb0d44d 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quaternion.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Quat" version="4.0"> +<class name="Quaternion" version="4.0"> <brief_description> Quaternion. </brief_description> <description> A unit quaternion used for representing 3D rotations. Quaternions need to be normalized to be used for rotation. - It is similar to Basis, which implements matrix representation of rotations, and can be parametrized using both an axis-angle pair or Euler angles. Basis stores rotation, scale, and shearing, while Quat only stores rotation. + It is similar to Basis, which implements matrix representation of rotations, and can be parametrized using both an axis-angle pair or Euler angles. Basis stores rotation, scale, and shearing, while Quaternion only stores rotation. Due to its compactness and the way it is stored in memory, certain operations (obtaining axis-angle and performing SLERP, in particular) are more efficient and robust against floating-point errors. </description> <tutorials> @@ -13,24 +13,24 @@ <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> </tutorials> <methods> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <description> Constructs a default-initialized quaternion with all components set to [code]0[/code]. </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> - <argument index="0" name="from" type="Quat"> + <argument index="0" name="from" type="Quaternion"> </argument> <description> - Constructs a [Quat] as a copy of the given [Quat]. + Constructs a [Quaternion] as a copy of the given [Quaternion]. </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <argument index="0" name="arc_from" type="Vector3"> </argument> @@ -39,8 +39,8 @@ <description> </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <argument index="0" name="axis" type="Vector3"> </argument> @@ -50,8 +50,8 @@ Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <argument index="0" name="euler" type="Vector3"> </argument> @@ -59,8 +59,8 @@ Constructs a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle, Z angle). </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <argument index="0" name="from" type="Basis"> </argument> @@ -68,8 +68,8 @@ Constructs a quaternion from the given [Basis]. </description> </method> - <method name="Quat" qualifiers="constructor"> - <return type="Quat"> + <method name="Quaternion" qualifiers="constructor"> + <return type="Quaternion"> </return> <argument index="0" name="x" type="float"> </argument> @@ -84,13 +84,13 @@ </description> </method> <method name="cubic_slerp" qualifiers="const"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="b" type="Quat"> + <argument index="0" name="b" type="Quaternion"> </argument> - <argument index="1" name="pre_a" type="Quat"> + <argument index="1" name="pre_a" type="Quaternion"> </argument> - <argument index="2" name="post_b" type="Quat"> + <argument index="2" name="post_b" type="Quaternion"> </argument> <argument index="3" name="weight" type="float"> </argument> @@ -101,7 +101,7 @@ <method name="dot" qualifiers="const"> <return type="float"> </return> - <argument index="0" name="with" type="Quat"> + <argument index="0" name="with" type="Quaternion"> </argument> <description> Returns the dot product of two quaternions. @@ -115,7 +115,7 @@ </description> </method> <method name="inverse" qualifiers="const"> - <return type="Quat"> + <return type="Quaternion"> </return> <description> Returns the inverse of the quaternion. @@ -124,7 +124,7 @@ <method name="is_equal_approx" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="to" type="Quat"> + <argument index="0" name="to" type="Quaternion"> </argument> <description> Returns [code]true[/code] if this quaternion and [code]quat[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. @@ -152,7 +152,7 @@ </description> </method> <method name="normalized" qualifiers="const"> - <return type="Quat"> + <return type="Quaternion"> </return> <description> Returns a copy of the quaternion, normalized to unit length. @@ -161,15 +161,15 @@ <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> @@ -183,7 +183,7 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <argument index="0" name="right" type="float"> </argument> @@ -191,7 +191,7 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <argument index="0" name="right" type="int"> </argument> @@ -199,35 +199,35 @@ </description> </method> <method name="operator +" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <description> </description> </method> <method name="operator +" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> </method> <method name="operator -" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <description> </description> </method> <method name="operator -" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> </method> <method name="operator /" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <argument index="0" name="right" type="float"> </argument> @@ -235,7 +235,7 @@ </description> </method> <method name="operator /" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> <argument index="0" name="right" type="int"> </argument> @@ -245,7 +245,7 @@ <method name="operator ==" qualifiers="operator"> <return type="bool"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> @@ -259,9 +259,9 @@ </description> </method> <method name="slerp" qualifiers="const"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="to" type="Quat"> + <argument index="0" name="to" type="Quaternion"> </argument> <argument index="1" name="weight" type="float"> </argument> @@ -271,9 +271,9 @@ </description> </method> <method name="slerpni" qualifiers="const"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="to" type="Quat"> + <argument index="0" name="to" type="Quaternion"> </argument> <argument index="1" name="weight" type="float"> </argument> @@ -301,7 +301,7 @@ </member> </members> <constants> - <constant name="IDENTITY" value="Quat( 0, 0, 0, 1 )"> + <constant name="IDENTITY" value="Quaternion( 0, 0, 0, 1 )"> The identity quaternion, representing no rotation. Equivalent to an identity [Basis] matrix. If a vector is transformed by an identity quaternion, it will not change. </constant> </constants> diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml index cd08778c89..13df17cd22 100644 --- a/doc/classes/ReflectionProbe.xml +++ b/doc/classes/ReflectionProbe.xml @@ -5,7 +5,7 @@ </brief_description> <description> Captures its surroundings as a cubemap, and stores versions of it with increasing levels of blur to simulate different material roughnesses. - The [ReflectionProbe] is used to create high-quality reflections at the cost of performance. It can be combined with [GIProbe]s and Screen Space Reflections to achieve high quality reflections. [ReflectionProbe]s render all objects within their [member cull_mask], so updating them can be quite expensive. It is best to update them once with the important static objects and then leave them. + The [ReflectionProbe] is used to create high-quality reflections at the cost of performance. It can be combined with [VoxelGI]s and Screen Space Reflections to achieve high quality reflections. [ReflectionProbe]s render all objects within their [member cull_mask], so updating them can be quite expensive. It is best to update them once with the important static objects and then leave them. </description> <tutorials> <link title="Reflection probes">https://docs.godotengine.org/en/latest/tutorials/3d/reflection_probes.html</link> diff --git a/doc/classes/RemoteTransform3D.xml b/doc/classes/RemoteTransform3D.xml index bd3da2aea9..453177496f 100644 --- a/doc/classes/RemoteTransform3D.xml +++ b/doc/classes/RemoteTransform3D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="RemoteTransform3D" inherits="Node3D" version="4.0"> <brief_description> - RemoteTransform3D pushes its own [Transform] to another [Node3D] derived Node in the scene. + RemoteTransform3D pushes its own [Transform3D] to another [Node3D] derived Node in the scene. </brief_description> <description> - RemoteTransform3D pushes its own [Transform] to another [Node3D] derived Node (called the remote node) in the scene. + RemoteTransform3D pushes its own [Transform3D] to another [Node3D] derived Node (called the remote node) in the scene. It can be set to update another Node's position, rotation and/or scale. It can use either global or local coordinates. </description> <tutorials> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 7a345f726d..ba19176788 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -130,10 +130,10 @@ </return> <argument index="0" name="camera" type="RID"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> - Sets [Transform] of camera. + Sets [Transform3D] of camera. </description> </method> <method name="camera_set_use_vertical_aspect"> @@ -1335,7 +1335,7 @@ </return> <argument index="0" name="instance" type="RID"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> Sets the world space transform of the instance. Equivalent to [member Node3D.transform]. @@ -1894,14 +1894,14 @@ </description> </method> <method name="multimesh_instance_get_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="multimesh" type="RID"> </argument> <argument index="1" name="index" type="int"> </argument> <description> - Returns the [Transform] of the specified instance. + Returns the [Transform3D] of the specified instance. </description> </method> <method name="multimesh_instance_get_transform_2d" qualifiers="const"> @@ -1948,10 +1948,10 @@ </argument> <argument index="1" name="index" type="int"> </argument> - <argument index="2" name="transform" type="Transform"> + <argument index="2" name="transform" type="Transform3D"> </argument> <description> - Sets the [Transform] for this instance. Equivalent to [method MultiMesh.set_instance_transform]. + Sets the [Transform3D] for this instance. Equivalent to [method MultiMesh.set_instance_transform]. </description> </method> <method name="multimesh_instance_set_transform_2d"> @@ -2142,10 +2142,10 @@ </return> <argument index="0" name="particles" type="RID"> </argument> - <argument index="1" name="transform" type="Transform"> + <argument index="1" name="transform" type="Transform3D"> </argument> <description> - Sets the [Transform] that will be used by the particles when they first emit. + Sets the [Transform3D] that will be used by the particles when they first emit. </description> </method> <method name="particles_set_emitting"> @@ -2590,14 +2590,14 @@ </description> </method> <method name="skeleton_bone_get_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="skeleton" type="RID"> </argument> <argument index="1" name="bone" type="int"> </argument> <description> - Returns the [Transform] set for a specific bone of this skeleton. + Returns the [Transform3D] set for a specific bone of this skeleton. </description> </method> <method name="skeleton_bone_get_transform_2d" qualifiers="const"> @@ -2618,10 +2618,10 @@ </argument> <argument index="1" name="bone" type="int"> </argument> - <argument index="2" name="transform" type="Transform"> + <argument index="2" name="transform" type="Transform3D"> </argument> <description> - Sets the [Transform] for a specific bone of this skeleton. + Sets the [Transform3D] for a specific bone of this skeleton. </description> </method> <method name="skeleton_bone_set_transform_2d"> @@ -3267,7 +3267,7 @@ Use [Transform2D] to store MultiMesh transform. </constant> <constant name="MULTIMESH_TRANSFORM_3D" value="1" enum="MultimeshTransformFormat"> - Use [Transform] to store MultiMesh transform. + Use [Transform3D] to store MultiMesh transform. </constant> <constant name="LIGHT_DIRECTIONAL" value="0" enum="LightType"> Is a directional (sun) light. @@ -3477,14 +3477,14 @@ <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 name="VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO" value="6" enum="ViewportDebugDraw"> + Objects are displayed with only the albedo value from [VoxelGI]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 name="VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING" value="7" enum="ViewportDebugDraw"> + Objects are displayed with only the lighting value from [VoxelGI]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 name="VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION" value="8" enum="ViewportDebugDraw"> + Objects are displayed with only the emission color from [VoxelGI]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]. @@ -3694,8 +3694,8 @@ <constant name="INSTANCE_DECAL" value="8" enum="InstanceType"> The instance is a decal. </constant> - <constant name="INSTANCE_GI_PROBE" value="9" enum="InstanceType"> - The instance is a GI probe. + <constant name="INSTANCE_VOXEL_GI" value="9" enum="InstanceType"> + The instance is a VoxelGI. </constant> <constant name="INSTANCE_LIGHTMAP" value="10" enum="InstanceType"> The instance is a lightmap. diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml index ecde5754f9..437b0ce730 100644 --- a/doc/classes/ResourceSaver.xml +++ b/doc/classes/ResourceSaver.xml @@ -49,7 +49,7 @@ Do not save editor-specific metadata (identified by their [code]__editor[/code] prefix). </constant> <constant name="FLAG_SAVE_BIG_ENDIAN" value="16" enum="SaverFlags"> - Save as big endian (see [member File.endian_swap]). + Save as big endian (see [member File.big_endian]). </constant> <constant name="FLAG_COMPRESS" value="32" enum="SaverFlags"> Compress the resource on save using [constant File.COMPRESSION_ZSTD]. Only available for binary resource types. diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index a37ebb2dd5..237317daf1 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -5,7 +5,7 @@ </brief_description> <description> This node implements simulated 2D physics. You do not control a RigidBody2D directly. Instead, you apply forces to it (gravity, impulses, etc.) and the physics simulation calculates the resulting movement based on its mass, friction, and other physical properties. - A RigidBody2D has 4 behavior [member mode]s: Rigid, Static, Character, and Kinematic. + A RigidBody2D has 4 behavior [member mode]s: Dynamic, Static, DynamicLocked, and Kinematic. [b]Note:[/b] You should not change a RigidBody2D's [code]position[/code] or [code]linear_velocity[/code] every frame or even very often. If you need to directly affect the body's state, use [method _integrate_forces], which allows you to directly access the physics state. Please also keep in mind that physics bodies manage their own transform which overwrites the ones you set. So any direct or indirect transformation (including scaling of the node or its parent) will be visible in the editor only, and immediately reset at runtime. If you need to override the default physics behavior or add a transformation at runtime, you can write a custom force integration. See [member custom_integrator]. @@ -100,21 +100,6 @@ Sets the body's velocity on the given axis. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior. </description> </method> - <method name="test_motion"> - <return type="bool"> - </return> - <argument index="0" name="motion" type="Vector2"> - </argument> - <argument index="1" name="infinite_inertia" type="bool" default="true"> - </argument> - <argument index="2" name="margin" type="float" default="0.08"> - </argument> - <argument index="3" name="result" type="PhysicsTestMotionResult2D" default="null"> - </argument> - <description> - Returns [code]true[/code] if a collision would result from moving in the given vector. [code]margin[/code] increases the size of the shapes involved in the collision detection, and [code]result[/code] is an object of type [PhysicsTestMotionResult2D], which contains additional information about the collision (should there be one). - </description> - </method> </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="-1.0"> @@ -132,7 +117,6 @@ </member> <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true"> If [code]true[/code], the body can enter sleep mode when there is no movement. See [member sleeping]. - [b]Note:[/b] A RigidBody2D will never enter sleep mode automatically if its [member mode] is [constant MODE_CHARACTER]. It can still be put to sleep manually by setting its [member sleeping] property to [code]true[/code]. </member> <member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false"> If [code]true[/code], the body will emit signals when it collides with another RigidBody2D. See also [member contacts_reported]. @@ -234,17 +218,17 @@ </signal> </signals> <constants> - <constant name="MODE_RIGID" value="0" enum="Mode"> - Rigid mode. The body behaves as a physical object. It collides with other bodies and responds to forces applied to it. This is the default mode. + <constant name="MODE_DYNAMIC" value="0" enum="Mode"> + Dynamic body mode. This is the default mode of a rigid body. It is affected by forces, and can move, rotate, and be affected by user code. </constant> <constant name="MODE_STATIC" value="1" enum="Mode"> - Static mode. The body behaves like a [StaticBody2D] and does not move. + Static body mode. The body behaves like a [StaticBody2D], and must be moved by code. </constant> - <constant name="MODE_CHARACTER" value="2" enum="Mode"> - Character mode. Similar to [constant MODE_RIGID], but the body can not rotate. + <constant name="MODE_DYNAMIC_LOCKED" value="2" enum="Mode"> + Locked dynamic body mode. Similar to [constant MODE_DYNAMIC], but the body can not rotate. </constant> <constant name="MODE_KINEMATIC" value="3" enum="Mode"> - Kinematic mode. The body behaves like a [KinematicBody2D], and must be moved by code. + Kinematic body mode. The body behaves like a [StaticBody2D] with [member StaticBody2D.kinematic_motion] enabled, and must be moved by user code. </constant> <constant name="CCD_MODE_DISABLED" value="0" enum="CCDMode"> Continuous collision detection disabled. This is the fastest way to detect body collisions, but can miss small, fast-moving objects. diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index 2ee8e2697c..e3349169ff 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -5,7 +5,7 @@ </brief_description> <description> This is the node that implements full 3D physics. This means that you do not control a RigidBody3D directly. Instead, you can apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate the resulting movement, collision, bouncing, rotating, etc. - A RigidBody3D has 4 behavior [member mode]s: Rigid, Static, Character, and Kinematic. + A RigidBody3D has 4 behavior [member mode]s: Dynamic, Static, DynamicLocked, and Kinematic. [b]Note:[/b] Don't change a RigidBody3D's position every frame or very often. Sporadic changes work fine, but physics runs at a different granularity (fixed Hz) than usual rendering (process callback) and maybe even in a separate thread, so changing this from a process loop may result in strange behavior. If you need to directly affect the body's state, use [method _integrate_forces], which allows you to directly access the physics state. If you need to override the default physics behavior, you can write a custom force integration function. See [member custom_integrator]. With Bullet physics (the default), the center of mass is the RigidBody3D center. With GodotPhysics, the center of mass is the average of the [CollisionShape3D] centers. @@ -86,15 +86,6 @@ Applies a torque impulse which will be affected by the body mass and shape. This will rotate the body around the [code]impulse[/code] vector passed. </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> - Returns [code]true[/code] if the specified linear or rotational axis is locked. - </description> - </method> <method name="get_colliding_bodies" qualifiers="const"> <return type="Array"> </return> @@ -110,17 +101,6 @@ Returns the inverse inertia tensor basis. This is used to calculate the angular acceleration resulting from a torque applied to the [RigidBody3D]. </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> - Locks the specified linear or rotational axis. - </description> - </method> <method name="set_axis_velocity"> <return type="void"> </return> @@ -139,27 +119,8 @@ <member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity" default="Vector3( 0, 0, 0 )"> RigidBody3D's rotational velocity. </member> - <member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the X axis. - </member> - <member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the Y axis. - </member> - <member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's rotation in the Z axis. - </member> - <member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the X axis. - </member> - <member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the Y axis. - </member> - <member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> - Lock the body's movement in the Z axis. - </member> <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true"> If [code]true[/code], the body can enter sleep mode when there is no movement. See [member sleeping]. - [b]Note:[/b] A RigidBody3D will never enter sleep mode automatically if its [member mode] is [constant MODE_CHARACTER]. It can still be put to sleep manually by setting its [member sleeping] property to [code]true[/code]. </member> <member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false"> If [code]true[/code], the RigidBody3D will emit signals when it collides with another RigidBody3D. See also [member contacts_reported]. @@ -260,17 +221,17 @@ </signal> </signals> <constants> - <constant name="MODE_RIGID" value="0" enum="Mode"> - Rigid body mode. This is the "natural" state of a rigid body. It is affected by forces, and can move, rotate, and be affected by user code. + <constant name="MODE_DYNAMIC" value="0" enum="Mode"> + Dynamic body mode. This is the default mode of a rigid body. It is affected by forces, and can move, rotate, and be affected by user code. </constant> <constant name="MODE_STATIC" value="1" enum="Mode"> - Static mode. The body behaves like a [StaticBody3D], and can only move by user code. + Static body mode. The body behaves like a [StaticBody3D], and can only move by user code. </constant> - <constant name="MODE_CHARACTER" value="2" enum="Mode"> - Character body mode. This behaves like a rigid body, but can not rotate. + <constant name="MODE_DYNAMIC_LOCKED" value="2" enum="Mode"> + Locked dynamic body mode. Similar to [constant MODE_DYNAMIC], but the body can not rotate. </constant> <constant name="MODE_KINEMATIC" value="3" enum="Mode"> - Kinematic body mode. The body behaves like a [KinematicBody3D], and can only move by user code. + Kinematic body mode. The body behaves like a [StaticBody3D] with [member StaticBody3D.kinematic_motion] enabled, and can only move by user code. </constant> </constants> </class> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 06800082cb..7a15153fc2 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -207,6 +207,7 @@ Quits the application at the end of the current iteration. Argument [code]exit_code[/code] can optionally be given (defaulting to 0) to customize the exit status code. By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. For portability reasons, the exit code should be set between 0 and 125 (inclusive). + [b]Note:[/b] On iOS this method doesn't work. Instead, as recommended by the iOS Human Interface Guidelines, the user is expected to close apps via the Home button. </description> </method> <method name="reload_current_scene"> diff --git a/doc/classes/Skeleton2D.xml b/doc/classes/Skeleton2D.xml index 0ddbac9ba4..6665a4a9f6 100644 --- a/doc/classes/Skeleton2D.xml +++ b/doc/classes/Skeleton2D.xml @@ -10,6 +10,17 @@ <link title="2D skeletons">https://docs.godotengine.org/en/latest/tutorials/animation/2d_skeletons.html</link> </tutorials> <methods> + <method name="execute_modifications"> + <return type="void"> + </return> + <argument index="0" name="delta" type="float"> + </argument> + <argument index="1" name="execution_mode" type="int"> + </argument> + <description> + Executes all the modifications on the [SkeletonModificationStack2D], if the Skeleton3D has one assigned. + </description> + </method> <method name="get_bone"> <return type="Bone2D"> </return> @@ -26,6 +37,22 @@ Returns the number of [Bone2D] nodes in the node hierarchy parented by Skeleton2D. </description> </method> + <method name="get_bone_local_pose_override"> + <return type="Transform2D"> + </return> + <argument index="0" name="bone_idx" type="int"> + </argument> + <description> + Returns the local pose override transform for [code]bone_idx[/code]. + </description> + </method> + <method name="get_modification_stack" qualifiers="const"> + <return type="SkeletonModificationStack2D"> + </return> + <description> + Returns the [SkeletonModificationStack2D] attached to this skeleton, if one exists. + </description> + </method> <method name="get_skeleton" qualifiers="const"> <return type="RID"> </return> @@ -33,10 +60,37 @@ Returns the [RID] of a Skeleton2D instance. </description> </method> + <method name="set_bone_local_pose_override"> + <return type="void"> + </return> + <argument index="0" name="bone_idx" type="int"> + </argument> + <argument index="1" name="override_pose" type="Transform2D"> + </argument> + <argument index="2" name="strength" type="float"> + </argument> + <argument index="3" name="persistent" type="bool"> + </argument> + <description> + Sets the local pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code]. + [code]amount[/code] is the interpolation strengh that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain. + [b]Note:[/b] The pose transform needs to be a local transform relative to the [Bone2D] node at [code]bone_idx[/code]! + </description> + </method> + <method name="set_modification_stack"> + <return type="void"> + </return> + <argument index="0" name="modification_stack" type="SkeletonModificationStack2D"> + </argument> + <description> + Sets the [SkeletonModificationStack2D] attached to this skeleton. + </description> + </method> </methods> <signals> <signal name="bone_setup_changed"> <description> + Emitted when the [Bone2D] setup attached to this skeletons changes. This is primarily used internally within the skeleton. </description> </signal> </signals> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 44ad460459..d8b35ad272 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -23,9 +23,9 @@ </description> </method> <method name="bone_transform_to_world_transform"> - <return type="Transform"> + <return type="Transform3D"> </return> - <argument index="0" name="bone_transform" type="Transform"> + <argument index="0" name="bone_transform" type="Transform3D"> </argument> <description> Takes the given bone pose/transform and converts it to a world transform, relative to the [Skeleton3D] node. @@ -63,7 +63,7 @@ </description> </method> <method name="get_bone_custom_pose" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bone_idx" type="int"> </argument> @@ -72,7 +72,7 @@ </description> </method> <method name="get_bone_global_pose" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bone_idx" type="int"> </argument> @@ -81,7 +81,7 @@ </description> </method> <method name="get_bone_global_pose_no_override" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bone_idx" type="int"> </argument> @@ -109,7 +109,7 @@ </description> </method> <method name="get_bone_pose" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bone_idx" type="int"> </argument> @@ -124,7 +124,7 @@ </description> </method> <method name="get_bone_rest" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bone_idx" type="int"> </argument> @@ -199,7 +199,7 @@ </return> <argument index="0" name="bone_idx" type="int"> </argument> - <argument index="1" name="custom_pose" type="Transform"> + <argument index="1" name="custom_pose" type="Transform3D"> </argument> <description> Sets the custom pose transform, [code]custom_pose[/code], for the bone at [code]bone_idx[/code]. This pose is an addition to the bone rest pose. @@ -222,7 +222,7 @@ </return> <argument index="0" name="bone_idx" type="int"> </argument> - <argument index="1" name="pose" type="Transform"> + <argument index="1" name="pose" type="Transform3D"> </argument> <argument index="2" name="amount" type="float"> </argument> @@ -261,7 +261,7 @@ </return> <argument index="0" name="bone_idx" type="int"> </argument> - <argument index="1" name="pose" type="Transform"> + <argument index="1" name="pose" type="Transform3D"> </argument> <description> Sets the pose transform for bone [code]bone_idx[/code]. @@ -273,7 +273,7 @@ </return> <argument index="0" name="bone_idx" type="int"> </argument> - <argument index="1" name="rest" type="Transform"> + <argument index="1" name="rest" type="Transform3D"> </argument> <description> Sets the rest transform for bone [code]bone_idx[/code]. @@ -289,9 +289,9 @@ </description> </method> <method name="world_transform_to_bone_transform"> - <return type="Transform"> + <return type="Transform3D"> </return> - <argument index="0" name="world_transform" type="Transform"> + <argument index="0" name="world_transform" type="Transform3D"> </argument> <description> Takes the given world transform, relative to the [Skeleton3D], and converts it to a bone pose/transform. diff --git a/doc/classes/SkeletonIK3D.xml b/doc/classes/SkeletonIK3D.xml index 5193109447..5949ad54fd 100644 --- a/doc/classes/SkeletonIK3D.xml +++ b/doc/classes/SkeletonIK3D.xml @@ -48,7 +48,7 @@ </member> <member name="root_bone" type="StringName" setter="set_root_bone" getter="get_root_bone" default="@"""> </member> - <member name="target" type="Transform" setter="set_target_transform" getter="get_target_transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <member name="target" type="Transform3D" setter="set_target_transform" getter="get_target_transform" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </member> <member name="target_node" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> </member> diff --git a/doc/classes/SkeletonModification2D.xml b/doc/classes/SkeletonModification2D.xml new file mode 100644 index 0000000000..8596dac76e --- /dev/null +++ b/doc/classes/SkeletonModification2D.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2D" inherits="Resource" version="4.0"> + <brief_description> + A resource that operates on [Bone2D] nodes in a [Skeleton2D]. + </brief_description> + <description> + This resource provides an interface that can be expanded so code that operates on [Bone2D] nodes in a [Skeleton2D] can be mixed and matched together to create complex interactions. + This is used to provide Godot with a flexible and powerful Inverse Kinematics solution that can be adapted for many different uses. + </description> + <tutorials> + </tutorials> + <methods> + <method name="_draw_editor_gizmo" qualifiers="virtual"> + <return type="void"> + </return> + <description> + Used for drawing [b]editor-only[/b] modification gizmos. This function will only be called in the Godot editor and can be overriden to draw custom gizmos. + [b]Note:[/b] You will need to use the Skeleton2D from [method SkeletonModificationStack2D.get_skeleton] and it's draw functions, as the [SkeletonModification2D] resource cannot draw on its own. + </description> + </method> + <method name="_execute" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="delta" type="float"> + </argument> + <description> + Executes the given modification. This is where the modification performs whatever function it is designed to do. + </description> + </method> + <method name="_setup_modification" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="modification_stack" type="SkeletonModificationStack2D"> + </argument> + <description> + Called when the modification is setup. This is where the modification performs initialization. + </description> + </method> + <method name="clamp_angle"> + <return type="float"> + </return> + <argument index="0" name="angle" type="float"> + </argument> + <argument index="1" name="min" type="float"> + </argument> + <argument index="2" name="max" type="float"> + </argument> + <argument index="3" name="invert" type="bool"> + </argument> + <description> + Takes a angle and clamps it so it is within the passed-in [code]min[/code] and [code]max[/code] range. [code]invert[/code] will inversely clamp the angle, clamping it to the range outside of the given bounds. + </description> + </method> + <method name="get_editor_draw_gizmo" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether this modification will call [method _draw_editor_gizmo] in the Godot editor to draw modification-specific gizmos. + </description> + </method> + <method name="get_is_setup" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether this modification has been successfully setup or not. + </description> + </method> + <method name="get_modification_stack"> + <return type="SkeletonModificationStack2D"> + </return> + <description> + Returns the [SkeletonModificationStack2D] that this modification is bound to. Through the modification stack, you can access the Skeleton3D the modification is operating on. + </description> + </method> + <method name="set_editor_draw_gizmo"> + <return type="void"> + </return> + <argument index="0" name="draw_gizmo" type="bool"> + </argument> + <description> + Sets whether this modification will call [method _draw_editor_gizmo] in the Godot editor to draw modification-specific gizmos. + </description> + </method> + <method name="set_is_setup"> + <return type="void"> + </return> + <argument index="0" name="is_setup" type="bool"> + </argument> + <description> + Manually allows you to set the setup state of the modification. This function should only rarely be used, as the [SkeletonModificationStack2D] the modification is bound to should handle setting the modification up. + </description> + </method> + </methods> + <members> + <member name="enabled" type="bool" setter="set_enabled" getter="get_enabled" default="true"> + If [code]true[/code], the modification's [method _execute] function will be called by the [SkeletonModificationStack2D]. + </member> + <member name="execution_mode" type="int" setter="set_execution_mode" getter="get_execution_mode" default="0"> + The execution mode for the modification. This tells the modification stack when to execute the modification. Some modifications have settings that are only availible in certain execution modes. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DCCDIK.xml b/doc/classes/SkeletonModification2DCCDIK.xml new file mode 100644 index 0000000000..014d366a42 --- /dev/null +++ b/doc/classes/SkeletonModification2DCCDIK.xml @@ -0,0 +1,170 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DCCDIK" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that uses CCDIK to manipulate a series of bones to reach a target in 2D. + </brief_description> + <description> + This [SkeletonModification2D] uses an algorithm called [b]C[/b]yclic [b]C[/b]oordinate [b]D[/b]escent [b]I[/b]nverse [b]K[/b]inematics, or CCDIK, to maniuplate a chain of bones in a [Skeleton2D] so it reaches a defined target. + CCDIK works by rotating a set of bones, typically called a "bone chain", on a single axis. Each bone is rotated to face the target from the tip (by default), which over a chain of bones allow it to rotate properly to reach the target. Because the bones only rotate on a single axis, CCDIK [i]can[/i] look more robotic than other IK solvers. + [b]Note:[/b] The CCDIK modifier has [code]ccdik_joints[/code], which are the data objects that hold the data for each joint in the CCDIK chain. This is different from a bone! CCDIK joints hold the data needed for each bone in the bone chain used by CCDIK. + CCDIK also fully supports angle constraints, allowing for more control over how a solution is met. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_ccdik_joint_bone2d_node" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the [Bone2D] node assigned to the CCDIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_ccdik_joint_bone_index" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the index of the [Bone2D] node assigned to the CCDIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_ccdik_joint_constraint_angle_invert" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns whether the CCDIK joint at [code]joint_idx[/code] uses an inverted joint constraint. See [method set_ccdik_joint_constraint_angle_invert] for details. + </description> + </method> + <method name="get_ccdik_joint_constraint_angle_max" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the maximum angle constraint for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_ccdik_joint_constraint_angle_min" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the minimum angle constraint for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_ccdik_joint_enable_constraint" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns whether angle constraints on the CCDIK joint at [code]joint_idx[/code] are enabled. + </description> + </method> + <method name="get_ccdik_joint_rotate_from_joint" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns whether the joint at [code]joint_idx[/code] is set to rotate from the joint, [code]true[/code], or to rotate from the tip, [code]false[/code]. The default is to rotate from the tip. + </description> + </method> + <method name="set_ccdik_joint_bone2d_node"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone2d_nodepath" type="NodePath"> + </argument> + <description> + Sets the [Bone2D] node assigned to the CCDIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_ccdik_joint_bone_index"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone_idx" type="int"> + </argument> + <description> + Sets the bone index, [code]bone_index[/code], of the CCDIK joint at [code]joint_idx[/code]. When possible, this will also update the [code]bone2d_node[/code] of the CCDIK joint based on data provided by the linked skeleton. + </description> + </method> + <method name="set_ccdik_joint_constraint_angle_invert"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="invert" type="bool"> + </argument> + <description> + Sets whether the CCDIK joint at [code]joint_idx[/code] uses an inverted joint constraint. + An inverted joint constraint only constraints the CCDIK joint to the angles [i]outside of[/i] the inputted minimum and maximum angles. For this reason, it is referred to as an inverted joint constraint, as it constraints the joint to the outside of the inputted values. + </description> + </method> + <method name="set_ccdik_joint_constraint_angle_max"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="angle_max" type="float"> + </argument> + <description> + Sets the maximum angle constraint for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_ccdik_joint_constraint_angle_min"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="angle_min" type="float"> + </argument> + <description> + Sets the minimum angle constraint for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_ccdik_joint_enable_constraint"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="enable_constraint" type="bool"> + </argument> + <description> + Determines whether angle constraints on the CCDIK joint at [code]joint_idx[/code] are enabled. When [code]true[/code], constraints will be enabled and taken into account when solving. + </description> + </method> + <method name="set_ccdik_joint_rotate_from_joint"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="rotate_from_joint" type="bool"> + </argument> + <description> + Sets whether the joint at [code]joint_idx[/code] is set to rotate from the joint, [code]true[/code], or to rotate from the tip, [code]false[/code]. + </description> + </method> + </methods> + <members> + <member name="ccdik_data_chain_length" type="int" setter="set_ccdik_data_chain_length" getter="get_ccdik_data_chain_length" default="0"> + The amount of CCDIK joints in the CCDIK modification. + </member> + <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The NodePath to the node that is the target for the CCDIK modification. This node is what the CCDIK chain will attempt to rotate the bone chain to. + </member> + <member name="tip_nodepath" type="NodePath" setter="set_tip_node" getter="get_tip_node" default="NodePath("")"> + The end position of the CCDIK chain. Typically, this should be a child of a [Bone2D] node attached to the final [Bone2D] in the CCDIK chain. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DFABRIK.xml b/doc/classes/SkeletonModification2DFABRIK.xml new file mode 100644 index 0000000000..62ab34b06f --- /dev/null +++ b/doc/classes/SkeletonModification2DFABRIK.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DFABRIK" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that uses FABRIK to manipulate a series of [Bone2D] nodes to reach a target. + </brief_description> + <description> + This [SkeletonModification2D] uses an algorithm called [b]F[/b]orward [b]A[/b]nd [b]B[/b]ackward [b]R[/b]eaching [b]I[/b]nverse [b]K[/b]inematics, or FABRIK, to rotate a bone chain so that it reaches a target. + FABRIK works by knowing the positions and lengths of a series of bones, typically called a "bone chain". It first starts by running a forward pass, which places the final bone at the target's position. Then all other bones are moved towards the tip bone, so they stay at the defined bone length away. Then a backwards pass is performed, where the root/first bone in the FABRIK chain is placed back at the origin. then all other bones are moved so they stay at the defined bone length away. This positions the bone chain so that it reaches the target when possible, but all of the bones stay the correct length away from each other. + Because of how FABRIK works, it often gives more natural results than those seen in [SkeletonModification2DCCDIK]. FABRIK also supports angle constraints, which are fully taken into account when solving. + [b]Note:[/b] The FABRIK modifier has [code]fabrik_joints[/code], which are the data objects that hold the data for each joint in the FABRIK chain. This is different from [Bone2D] nodes! FABRIK joints hold the data needed for each [Bone2D] in the bone chain used by FABRIK. + To help control how the FABRIK joints move, a magnet vector can be passed, which can nudge the bones in a certain direction prior to solving, giving a level of control over the final result. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_fabrik_joint_bone2d_node" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the [Bone2D] node assigned to the FABRIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_fabrik_joint_bone_index" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the index of the [Bone2D] node assigned to the FABRIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_fabrik_joint_magnet_position" qualifiers="const"> + <return type="Vector2"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the magnet position vector for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_fabrik_joint_use_target_rotation" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns whether the joint is using the target's rotation rather than allowing FABRIK to rotate the joint. This option only applies to the tip/final joint in the chain. + </description> + </method> + <method name="set_fabrik_joint_bone2d_node"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone2d_nodepath" type="NodePath"> + </argument> + <description> + Sets the [Bone2D] node assigned to the FABRIK joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_fabrik_joint_bone_index"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone_idx" type="int"> + </argument> + <description> + Sets the bone index, [code]bone_index[/code], of the FABRIK joint at [code]joint_idx[/code]. When possible, this will also update the [code]bone2d_node[/code] of the FABRIK joint based on data provided by the linked skeleton. + </description> + </method> + <method name="set_fabrik_joint_magnet_position"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="magnet_position" type="Vector2"> + </argument> + <description> + Sets the magnet position vector for the joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_fabrik_joint_use_target_rotation"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="use_target_rotation" type="bool"> + </argument> + <description> + Sets whether the joint at [code]joint_idx[/code] will use the target node's rotation rather than letting FABRIK rotate the node. + [b]Note:[/b] This option only works for the tip/final joint in the chain. For all other nodes, this option will be ignored. + </description> + </method> + </methods> + <members> + <member name="fabrik_data_chain_length" type="int" setter="set_fabrik_data_chain_length" getter="get_fabrik_data_chain_length" default="0"> + The amount of FABRIK joints in the FABRIK modification. + </member> + <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The NodePath to the node that is the target for the FABRIK modification. This node is what the FABRIK chain will attempt to rotate the bone chain to. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DJiggle.xml b/doc/classes/SkeletonModification2DJiggle.xml new file mode 100644 index 0000000000..7f8cf2d4d9 --- /dev/null +++ b/doc/classes/SkeletonModification2DJiggle.xml @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DJiggle" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that jiggles [Bone2D] nodes as they move towards a target. + </brief_description> + <description> + This modification moves a series of bones, typically called a bone chain, towards a target. What makes this modification special is that it calculates the velocity and acceleration for each bone in the bone chain, and runs a very light physics-like calculation using the inputted values. This allows the bones to overshoot the target and "jiggle" around. It can be configured to act more like a spring, or sway around like cloth might. + This modification is useful for adding additional motion to things like hair, the edges of clothing, and more. It has several settings to that allow control over how the joint moves when the target moves. + [b]Note:[/b] The Jiggle modifier has [code]jiggle_joints[/code], which are the data objects that hold the data for each joint in the Jiggle chain. This is different from than [Bone2D] nodes! Jiggle joints hold the data needed for each [Bone2D] in the bone chain used by the Jiggle modification. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_collision_mask" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the collision mask used by the Jiggle modifier when collisions are enabled. + </description> + </method> + <method name="get_jiggle_joint_bone2d_node" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the [Bone2D] node assigned to the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_jiggle_joint_bone_index" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the index of the [Bone2D] node assigned to the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_jiggle_joint_damping" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the amount of damping of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_jiggle_joint_gravity" qualifiers="const"> + <return type="Vector2"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns a [Vector2] representing the amount of gravity the Jiggle joint at [code]joint_idx[/code] is influenced by. + </description> + </method> + <method name="get_jiggle_joint_mass" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the amount of mass of the jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_jiggle_joint_override" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns a boolean that indiciates whether the joint at [code]joint_idx[/code] is overriding the default Jiggle joint data defined in the modification. + </description> + </method> + <method name="get_jiggle_joint_stiffness" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the stiffness of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="get_jiggle_joint_use_gravity" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns a boolean that indiciates whether the joint at [code]joint_idx[/code] is using gravity or not. + </description> + </method> + <method name="get_use_colliders" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether the jiggle modifier is taking physics colliders into account when solving. + </description> + </method> + <method name="set_collision_mask"> + <return type="void"> + </return> + <argument index="0" name="collision_mask" type="int"> + </argument> + <description> + Sets the collision mask that the Jiggle modifier will use when reacting to colliders, if the Jiggle modifier is set to take colliders into account. + </description> + </method> + <method name="set_jiggle_joint_bone2d_node"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone2d_node" type="NodePath"> + </argument> + <description> + Sets the [Bone2D] node assigned to the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_jiggle_joint_bone_index"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="bone_idx" type="int"> + </argument> + <description> + Sets the bone index, [code]bone_index[/code], of the Jiggle joint at [code]joint_idx[/code]. When possible, this will also update the [code]bone2d_node[/code] of the Jiggle joint based on data provided by the linked skeleton. + </description> + </method> + <method name="set_jiggle_joint_damping"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="damping" type="float"> + </argument> + <description> + Sets the amount of dampening of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_jiggle_joint_gravity"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="gravity" type="Vector2"> + </argument> + <description> + Sets the gravity vector of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_jiggle_joint_mass"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="mass" type="float"> + </argument> + <description> + Sets the of mass of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_jiggle_joint_override"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="override" type="bool"> + </argument> + <description> + Sets whether the Jiggle joint at [code]joint_idx[/code] should override the default Jiggle joint settings. Setting this to [code]true[/code] will make the joint use its own settings rather than the default ones attached to the modification. + </description> + </method> + <method name="set_jiggle_joint_stiffness"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="stiffness" type="float"> + </argument> + <description> + Sets the of stiffness of the Jiggle joint at [code]joint_idx[/code]. + </description> + </method> + <method name="set_jiggle_joint_use_gravity"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="use_gravity" type="bool"> + </argument> + <description> + Sets whether the Jiggle joint at [code]joint_idx[/code] should use gravity. + </description> + </method> + <method name="set_use_colliders"> + <return type="void"> + </return> + <argument index="0" name="use_colliders" type="bool"> + </argument> + <description> + If [code]true[/code], the Jiggle modifier will take colliders into account, keeping them from entering into these collision objects. + </description> + </method> + </methods> + <members> + <member name="damping" type="float" setter="set_damping" getter="get_damping" default="0.75"> + The default amount of dampening applied to the Jiggle joints, if they are not overriden. Higher values lead to more of the calculated velocity being applied. + </member> + <member name="gravity" type="Vector2" setter="set_gravity" getter="get_gravity" default="Vector2( 0, 6 )"> + The default amount of gravity applied to the Jiggle joints, if they are not overriden. + </member> + <member name="jiggle_data_chain_length" type="int" setter="set_jiggle_data_chain_length" getter="get_jiggle_data_chain_length" default="0"> + The amount of Jiggle joints in the Jiggle modification. + </member> + <member name="mass" type="float" setter="set_mass" getter="get_mass" default="0.75"> + The default amount of mass assigned to the Jiggle joints, if they are not overriden. Higher values lead to faster movements and more overshooting. + </member> + <member name="stiffness" type="float" setter="set_stiffness" getter="get_stiffness" default="3.0"> + The default amount of stiffness assigned to the Jiggle joints, if they are not overriden. Higher values act more like springs, quickly moving into the correct position. + </member> + <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The NodePath to the node that is the target for the Jiggle modification. This node is what the Jiggle chain will attempt to rotate the bone chain to. + </member> + <member name="use_gravity" type="bool" setter="set_use_gravity" getter="get_use_gravity" default="false"> + Whether the gravity vector, [member gravity], should be applied to the Jiggle joints, assuming they are not overriding the default settings. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DLookAt.xml b/doc/classes/SkeletonModification2DLookAt.xml new file mode 100644 index 0000000000..b0fa0e5a01 --- /dev/null +++ b/doc/classes/SkeletonModification2DLookAt.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DLookAt" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that rotates a [Bone2D] node to look at a target. + </brief_description> + <description> + This [SkeletonModification2D] rotates a bone to look a target. This is extremely helpful for moving character's head to look at the player, rotating a turret to look at a target, or any other case where you want to make a bone rotate towards something quickly and easily. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_additional_rotation" qualifiers="const"> + <return type="float"> + </return> + <description> + Returns the amount of additional rotation that is applied after the LookAt modification executes. + </description> + </method> + <method name="get_constraint_angle_invert" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns whether the constraints to this modification are inverted or not. + </description> + </method> + <method name="get_constraint_angle_max" qualifiers="const"> + <return type="float"> + </return> + <description> + Returns the constraint's maximum allowed angle. + </description> + </method> + <method name="get_constraint_angle_min" qualifiers="const"> + <return type="float"> + </return> + <description> + Returns the constraint's minimum allowed angle. + </description> + </method> + <method name="get_enable_constraint" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the LookAt modification is using constraints. + </description> + </method> + <method name="set_additional_rotation"> + <return type="void"> + </return> + <argument index="0" name="rotation" type="float"> + </argument> + <description> + Sets the amount of additional rotation that is to be applied after executing the modification. This allows for offsetting the results by the inputted rotation amount. + </description> + </method> + <method name="set_constraint_angle_invert"> + <return type="void"> + </return> + <argument index="0" name="invert" type="bool"> + </argument> + <description> + When [code]true[/code], the modification will use an inverted joint constraint. + An inverted joint constraint only constraints the [Bone2D] to the angles [i]outside of[/i] the inputted minimum and maximum angles. For this reason, it is referred to as an inverted joint constraint, as it constraints the joint to the outside of the inputted values. + </description> + </method> + <method name="set_constraint_angle_max"> + <return type="void"> + </return> + <argument index="0" name="angle_max" type="float"> + </argument> + <description> + Sets the constraint's maximum allowed angle. + </description> + </method> + <method name="set_constraint_angle_min"> + <return type="void"> + </return> + <argument index="0" name="angle_min" type="float"> + </argument> + <description> + Sets the constraint's minimum allowed angle. + </description> + </method> + <method name="set_enable_constraint"> + <return type="void"> + </return> + <argument index="0" name="enable_constraint" type="bool"> + </argument> + <description> + Sets whether this modification will use constraints or not. When [code]true[/code], constraints will be applied when solving the LookAt modification. + </description> + </method> + </methods> + <members> + <member name="bone2d_node" type="NodePath" setter="set_bone2d_node" getter="get_bone2d_node" default="NodePath("")"> + The [Bone2D] node that the modification will operate on. + </member> + <member name="bone_index" type="int" setter="set_bone_index" getter="get_bone_index" default="-1"> + The index of the [Bone2D] node that the modification will oeprate on. + </member> + <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The NodePath to the node that is the target for the LookAt modification. This node is what the modification will rotate the [Bone2D] to. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DPhysicalBones.xml b/doc/classes/SkeletonModification2DPhysicalBones.xml new file mode 100644 index 0000000000..d8aaf09a8e --- /dev/null +++ b/doc/classes/SkeletonModification2DPhysicalBones.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DPhysicalBones" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that applies the transforms of [PhysicalBone2D] nodes to [Bone2D] nodes. + </brief_description> + <description> + This modification takes the transforms of [PhysicalBone2D] nodes and applies them to [Bone2D] nodes. This allows the [Bone2D] nodes to react to physics thanks to the linked [PhysicalBone2D] nodes. + </description> + <tutorials> + </tutorials> + <methods> + <method name="fetch_physical_bones"> + <return type="void"> + </return> + <description> + Empties the list of [PhysicalBone2D] nodes and populates it will all [PhysicalBone2D] nodes that are children of the [Skeleton2D]. + </description> + </method> + <method name="get_physical_bone_node" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <description> + Returns the [PhysicalBone2D] node at [code]joint_idx[/code]. + </description> + </method> + <method name="set_physical_bone_node"> + <return type="void"> + </return> + <argument index="0" name="joint_idx" type="int"> + </argument> + <argument index="1" name="physicalbone2d_node" type="NodePath"> + </argument> + <description> + Sets the [PhysicalBone2D] node at [code]joint_idx[/code]. + [b]Note:[/b] This is just the index used for this modification, not the bone index used in the [Skeleton2D]. + </description> + </method> + <method name="start_simulation"> + <return type="void"> + </return> + <argument index="0" name="bones" type="StringName[]" default="[ ]"> + </argument> + <description> + Tell the [PhysicalBone2D] nodes to start simulating and interacting with the physics world. + Optionally, an array of bone names can be passed to this function, and that will cause only [PhysicalBone2D] nodes with those names to start simulating. + </description> + </method> + <method name="stop_simulation"> + <return type="void"> + </return> + <argument index="0" name="bones" type="StringName[]" default="[ ]"> + </argument> + <description> + Tell the [PhysicalBone2D] nodes to stop simulating and interacting with the physics world. + Optionally, an array of bone names can be passed to this function, and that will cause only [PhysicalBone2D] nodes with those names to stop simulating. + </description> + </method> + </methods> + <members> + <member name="physical_bone_chain_length" type="int" setter="set_physical_bone_chain_length" getter="get_physical_bone_chain_length" default="0"> + The amount of [PhysicalBone2D] nodes linked in this modification. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DStackHolder.xml b/doc/classes/SkeletonModification2DStackHolder.xml new file mode 100644 index 0000000000..313cf81482 --- /dev/null +++ b/doc/classes/SkeletonModification2DStackHolder.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DStackHolder" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that holds and executes a [SkeletonModificationStack2D]. + </brief_description> + <description> + This [SkeletonModification2D] holds a reference to a [SkeletonModificationStack2D], allowing you to use multiple modification stacks on a single [Skeleton2D]. + [b]Note:[/b] The modifications in the held [SkeletonModificationStack2D] will only be executed if their execution mode matches the execution mode of the SkeletonModification2DStackHolder. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_held_modification_stack" qualifiers="const"> + <return type="SkeletonModificationStack2D"> + </return> + <description> + Returns the [SkeletonModificationStack2D] that this modification is holding. + </description> + </method> + <method name="set_held_modification_stack"> + <return type="void"> + </return> + <argument index="0" name="held_modification_stack" type="SkeletonModificationStack2D"> + </argument> + <description> + Sets the [SkeletonModificationStack2D] that this modification is holding. This modification stack will then be executed when this modification is executed. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModification2DTwoBoneIK.xml b/doc/classes/SkeletonModification2DTwoBoneIK.xml new file mode 100644 index 0000000000..554515556b --- /dev/null +++ b/doc/classes/SkeletonModification2DTwoBoneIK.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModification2DTwoBoneIK" inherits="SkeletonModification2D" version="4.0"> + <brief_description> + A modification that rotates two bones using the law of cosigns to reach the target. + </brief_description> + <description> + This [SkeletonModification2D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns and the lengths of the bones to figure out what rotation the bones currently have, and what rotation they need to make a complete triangle, where the first bone, the second bone, and the target form the three verticies of the triangle. Because the algorithm works by making a triangle, it can only opperate on two bones. + TwoBoneIK is great for arms, legs, and really any joints that can be represented by just two bones that bend to reach a target. This solver is more lightweight than [SkeletonModification2DFABRIK], but gives similar, natural looking results. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_joint_one_bone2d_node" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + Returns the [Bone2D] node that is being used as the first bone in the TwoBoneIK modification. + </description> + </method> + <method name="get_joint_one_bone_idx" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the index of the [Bone2D] node that is being used as the first bone in the TwoBoneIK modification. + </description> + </method> + <method name="get_joint_two_bone2d_node" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + Returns the [Bone2D] node that is being used as the second bone in the TwoBoneIK modification. + </description> + </method> + <method name="get_joint_two_bone_idx" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the index of the [Bone2D] node that is being used as the second bone in the TwoBoneIK modification. + </description> + </method> + <method name="set_joint_one_bone2d_node"> + <return type="void"> + </return> + <argument index="0" name="bone2d_node" type="NodePath"> + </argument> + <description> + Sets the [Bone2D] node that is being used as the first bone in the TwoBoneIK modification. + </description> + </method> + <method name="set_joint_one_bone_idx"> + <return type="void"> + </return> + <argument index="0" name="bone_idx" type="int"> + </argument> + <description> + Sets the index of the [Bone2D] node that is being used as the first bone in the TwoBoneIK modification. + </description> + </method> + <method name="set_joint_two_bone2d_node"> + <return type="void"> + </return> + <argument index="0" name="bone2d_node" type="NodePath"> + </argument> + <description> + Sets the [Bone2D] node that is being used as the second bone in the TwoBoneIK modification. + </description> + </method> + <method name="set_joint_two_bone_idx"> + <return type="void"> + </return> + <argument index="0" name="bone_idx" type="int"> + </argument> + <description> + Sets the index of the [Bone2D] node that is being used as the second bone in the TwoBoneIK modification. + </description> + </method> + </methods> + <members> + <member name="flip_bend_direction" type="bool" setter="set_flip_bend_direction" getter="get_flip_bend_direction" default="false"> + If [code]true[/code], the bones in the modification will blend outward as opposed to inwards when contracting. If [code]false[/code], the bones will bend inwards when contracting. + </member> + <member name="target_maximum_distance" type="float" setter="set_target_maximum_distance" getter="get_target_maximum_distance" default="0.0"> + The maximum distance the target can be at. If the target is farther than this distance, the modification will solve as if it's at this maximum distance. When set to [code]0[/code], the modification will solve without distance constraints. + </member> + <member name="target_minimum_distance" type="float" setter="set_target_minimum_distance" getter="get_target_minimum_distance" default="0.0"> + The minimum distance the target can be at. If the target is closer than this distance, the modification will solve as if it's at this minimum distance. When set to [code]0[/code], the modification will solve without distance constraints. + </member> + <member name="target_nodepath" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The NodePath to the node that is the target for the TwoBoneIK modification. This node is what the modification will use when bending the [Bone2D] nodes. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/SkeletonModificationStack2D.xml b/doc/classes/SkeletonModificationStack2D.xml new file mode 100644 index 0000000000..35b899fe08 --- /dev/null +++ b/doc/classes/SkeletonModificationStack2D.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SkeletonModificationStack2D" inherits="Resource" version="4.0"> + <brief_description> + A resource that holds a stack of [SkeletonModification2D]s. + </brief_description> + <description> + This resource is used by the Skeleton and holds a stack of [SkeletonModification2D]s. + This controls the order of the modifications and how they are applied. Modification order is especially important for full-body IK setups, as you need to execute the modifications in the correct order to get the desired results. For example, you want to execute a modification on the spine [i]before[/i] the arms on a humanoid skeleton. + This resource also controls how strongly all of the modifications are applied to the [Skeleton2D]. + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_modification"> + <return type="void"> + </return> + <argument index="0" name="modification" type="SkeletonModification2D"> + </argument> + <description> + Adds the passed-in [SkeletonModification2D] to the stack. + </description> + </method> + <method name="delete_modification"> + <return type="void"> + </return> + <argument index="0" name="mod_idx" type="int"> + </argument> + <description> + Deletes the [SkeletonModification2D] at the index position [code]mod_idx[/code], if it exists. + </description> + </method> + <method name="enable_all_modifications"> + <return type="void"> + </return> + <argument index="0" name="enabled" type="bool"> + </argument> + <description> + Enables all [SkeletonModification2D]s in the stack. + </description> + </method> + <method name="execute"> + <return type="void"> + </return> + <argument index="0" name="delta" type="float"> + </argument> + <argument index="1" name="execution_mode" type="int"> + </argument> + <description> + Executes all of the [SkeletonModification2D]s in the stack that use the same execution mode as the passed-in [code]execution_mode[/code], starting from index [code]0[/code] to [member modification_count]. + [b]Note:[/b] The order of the modifications can matter depending on the modifications. For example, modifications on a spine should operate before modifications on the arms in order to get proper results. + </description> + </method> + <method name="get_is_setup" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns a boolean that indiciates whether the modification stack is setup and can execute. + </description> + </method> + <method name="get_modification" qualifiers="const"> + <return type="SkeletonModification2D"> + </return> + <argument index="0" name="mod_idx" type="int"> + </argument> + <description> + Returns the [SkeletonModification2D] at the passed-in index, [code]mod_idx[/code]. + </description> + </method> + <method name="get_skeleton" qualifiers="const"> + <return type="Skeleton2D"> + </return> + <description> + Returns the [Skeleton2D] node that the SkeletonModificationStack2D is bound to. + </description> + </method> + <method name="set_modification"> + <return type="void"> + </return> + <argument index="0" name="mod_idx" type="int"> + </argument> + <argument index="1" name="modification" type="SkeletonModification2D"> + </argument> + <description> + Sets the modification at [code]mod_idx[/code] to the passed-in modification, [code]modification[/code]. + </description> + </method> + <method name="setup"> + <return type="void"> + </return> + <description> + Sets up the modification stack so it can execute. This function should be called by [Skeleton2D] and shouldn't be manually called unless you know what you are doing. + </description> + </method> + </methods> + <members> + <member name="enabled" type="bool" setter="set_enabled" getter="get_enabled" default="false"> + If [code]true[/code], the modification's in the stack will be called. This is handled automatically through the [Skeleton2D] node. + </member> + <member name="modification_count" type="int" setter="set_modification_count" getter="get_modification_count" default="0"> + The number of modifications in the stack. + </member> + <member name="strength" type="float" setter="set_strength" getter="get_strength" default="1.0"> + The interpolation strength of the modifications in stack. A value of [code]0[/code] will make it where the modifications are not applied, a strength of [code]0.5[/code] will be half applied, and a strength of [code]1[/code] will allow the modifications to be fully applied and override the [Skeleton2D] [Bone2D] poses. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Skin.xml b/doc/classes/Skin.xml index e22feb42f0..f409b6c80c 100644 --- a/doc/classes/Skin.xml +++ b/doc/classes/Skin.xml @@ -12,7 +12,7 @@ </return> <argument index="0" name="bone" type="int"> </argument> - <argument index="1" name="pose" type="Transform"> + <argument index="1" name="pose" type="Transform3D"> </argument> <description> </description> @@ -46,7 +46,7 @@ </description> </method> <method name="get_bind_pose" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="bind_index" type="int"> </argument> @@ -86,7 +86,7 @@ </return> <argument index="0" name="bind_index" type="int"> </argument> - <argument index="1" name="pose" type="Transform"> + <argument index="1" name="pose" type="Transform3D"> </argument> <description> </description> diff --git a/doc/classes/StaticBody2D.xml b/doc/classes/StaticBody2D.xml index 2a5c1ea6f4..298339d5fc 100644 --- a/doc/classes/StaticBody2D.xml +++ b/doc/classes/StaticBody2D.xml @@ -4,8 +4,11 @@ Static body for 2D physics. </brief_description> <description> - Static body for 2D physics. A StaticBody2D is a body that is not intended to move. It is ideal for implementing objects in the environment, such as walls or platforms. - Additionally, a constant linear or angular velocity can be set for the static body, which will affect colliding bodies as if it were moving (for example, a conveyor belt). + Static body for 2D physics. A static body is a simple body that can't be moved by external forces or contacts. It is ideal for implementing objects in the environment, such as walls or platforms. In contrast to [RigidBody2D], they don't consume any CPU resources as long as they don't move. + They however have extra functionalities to move and affect other bodies: + [b]Constant velocity:[/b] [member constant_linear_velocity] and [member constant_angular_velocity] can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels). + [b]Transform change:[/b] Static bodies can be also moved by code. Unless [member kinematic_motion] is enabled, they are just teleported in this case and don't affect other bodies on their path. + [b]Kinematic motion:[/b] Static bodies can have [member kinematic_motion] enabled to make them kinematic bodies that can be moved by code and push other bodies on their path. </description> <tutorials> </tutorials> @@ -13,10 +16,14 @@ </methods> <members> <member name="constant_angular_velocity" type="float" setter="set_constant_angular_velocity" getter="get_constant_angular_velocity" default="0.0"> - The body's constant angular velocity. This does not rotate the body, but affects colliding bodies, as if it were rotating. + The body's constant angular velocity. This does not rotate the body (unless [member kinematic_motion] is enabled), but affects other bodies that touch it, as if it were rotating. </member> <member name="constant_linear_velocity" type="Vector2" setter="set_constant_linear_velocity" getter="get_constant_linear_velocity" default="Vector2( 0, 0 )"> - The body's constant linear velocity. This does not move the body, but affects colliding bodies, as if it were moving. + The body's constant linear velocity. This does not move the body (unless [member kinematic_motion] is enabled), but affects other bodies that touch it, as if it were moving. + </member> + <member name="kinematic_motion" type="bool" setter="set_kinematic_motion_enabled" getter="is_kinematic_motion_enabled" default="false"> + If [code]true[/code], the body will act the same as a [RigidBody2D] in [constant RigidBody2D.MODE_KINEMATIC] mode. + When the body is moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to [code]physics[/code]), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). </member> <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> The physics material override for the body. diff --git a/doc/classes/StaticBody3D.xml b/doc/classes/StaticBody3D.xml index 63a15cbe1d..5ffbb71522 100644 --- a/doc/classes/StaticBody3D.xml +++ b/doc/classes/StaticBody3D.xml @@ -4,8 +4,11 @@ Static body for 3D physics. </brief_description> <description> - Static body for 3D physics. A static body is a simple body that is not intended to move. In contrast to [RigidBody3D], they don't consume any CPU resources as long as they don't move. - Additionally, a constant linear or angular velocity can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels). + Static body for 3D physics. A static body is a simple body that can't be moved by external forces or contacts. It is ideal for implementing objects in the environment, such as walls or platforms. In contrast to [RigidBody3D], they don't consume any CPU resources as long as they don't move. + They however have extra functionalities to move and affect other bodies: + [b]Constant velocity:[/b] [member constant_linear_velocity] and [member constant_angular_velocity] can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels). + [b]Transform change:[/b] Static bodies can be also moved by code. Unless [member kinematic_motion] is enabled, they are just teleported in this case and don't affect other bodies on their path. + [b]Kinematic motion:[/b] Static bodies can have [member kinematic_motion] enabled to make them kinematic bodies that can be moved by code and push other bodies on their path. </description> <tutorials> <link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link> @@ -16,10 +19,14 @@ </methods> <members> <member name="constant_angular_velocity" type="Vector3" setter="set_constant_angular_velocity" getter="get_constant_angular_velocity" default="Vector3( 0, 0, 0 )"> - The body's constant angular velocity. This does not rotate the body, but affects other bodies that touch it, as if it was in a state of rotation. + The body's constant angular velocity. This does not rotate the body (unless [member kinematic_motion] is enabled), but affects other bodies that touch it, as if it were rotating. </member> <member name="constant_linear_velocity" type="Vector3" setter="set_constant_linear_velocity" getter="get_constant_linear_velocity" default="Vector3( 0, 0, 0 )"> - The body's constant linear velocity. This does not move the body, but affects other bodies that touch it, as if it was in a state of movement. + The body's constant linear velocity. This does not move the body (unless [member kinematic_motion] is enabled), but affects other bodies that touch it, as if it were moving. + </member> + <member name="kinematic_motion" type="bool" setter="set_kinematic_motion_enabled" getter="is_kinematic_motion_enabled" default="false"> + If [code]true[/code], the body will act the same as a [RigidBody3D] in [constant RigidBody3D.MODE_KINEMATIC] mode. + When the body is moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to [code]physics[/code]), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). </member> <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> The physics material override for the body. diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 1195e4aa2b..d434f5c2c9 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -76,10 +76,10 @@ </argument> <argument index="1" name="surface" type="int"> </argument> - <argument index="2" name="transform" type="Transform"> + <argument index="2" name="transform" type="Transform3D"> </argument> <description> - Append vertices from a given [Mesh] surface onto the current vertex array with specified [Transform]. + Append vertices from a given [Mesh] surface onto the current vertex array with specified [Transform3D]. </description> </method> <method name="begin"> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index fe63e434c9..9a96d8699c 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -976,7 +976,7 @@ </argument> <description> Returns [code]true[/code] if text buffer is configured to display hexadecimal codes in place of invalid characters. - Note: If set to [code]false[/code], nothing is displayed in place of invalid characters. + Note: If set to [code]false[/code], nothing is displayed in place of invalid characters. </description> </method> <method name="shaped_text_get_range" qualifiers="const"> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index 6ae7fbcf79..0dbf95376a 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -18,7 +18,7 @@ <return type="Transform2D"> </return> <description> - Constructs a default-initialized [Transform] set to [constant IDENTITY]. + Constructs a default-initialized [Transform2D] set to [constant IDENTITY]. </description> </method> <method name="Transform2D" qualifiers="constructor"> @@ -129,6 +129,16 @@ Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. </description> </method> + <method name="looking_at" qualifiers="const"> + <return type="Transform2D"> + </return> + <argument index="0" name="target" type="Vector2" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> + </argument> + <description> + Returns a copy of the transform rotated such that it's rotation on the X-axis points towards the [code]target[/code] position. + Operations take place in global space. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> @@ -138,33 +148,33 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Vector2"> + <return type="PackedVector2Array"> </return> - <argument index="0" name="right" type="Vector2"> + <argument index="0" name="right" type="PackedVector2Array"> </argument> <description> </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Rect2"> + <return type="Transform2D"> </return> - <argument index="0" name="right" type="Rect2"> + <argument index="0" name="right" type="Transform2D"> </argument> <description> </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Transform2D"> + <return type="Rect2"> </return> - <argument index="0" name="right" type="Transform2D"> + <argument index="0" name="right" type="Rect2"> </argument> <description> </description> </method> <method name="operator *" qualifiers="operator"> - <return type="PackedVector2Array"> + <return type="Vector2"> </return> - <argument index="0" name="right" type="PackedVector2Array"> + <argument index="0" name="right" type="Vector2"> </argument> <description> </description> @@ -210,6 +220,15 @@ Scales the transform by the given scale factor, using matrix multiplication. </description> </method> + <method name="set_rotation"> + <return type="void"> + </return> + <argument index="0" name="rotation" type="float"> + </argument> + <description> + Sets the transform's rotation (in radians). + </description> + </method> <method name="translated" qualifiers="const"> <return type="Transform2D"> </return> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform3D.xml index 9d8721e2de..0d49255523 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Transform" version="4.0"> +<class name="Transform3D" version="4.0"> <brief_description> 3D transformation (3×4 matrix). </brief_description> @@ -16,35 +16,35 @@ <link title="2.5D Demo">https://godotengine.org/asset-library/asset/583</link> </tutorials> <methods> - <method name="Transform" qualifiers="constructor"> - <return type="Transform"> + <method name="Transform3D" qualifiers="constructor"> + <return type="Transform3D"> </return> <description> - Constructs a default-initialized [Transform] set to [constant IDENTITY]. + Constructs a default-initialized [Transform3D] set to [constant IDENTITY]. </description> </method> - <method name="Transform" qualifiers="constructor"> - <return type="Transform"> + <method name="Transform3D" qualifiers="constructor"> + <return type="Transform3D"> </return> - <argument index="0" name="from" type="Transform"> + <argument index="0" name="from" type="Transform3D"> </argument> <description> - Constructs a [Transform] as a copy of the given [Transform]. + Constructs a [Transform3D] as a copy of the given [Transform3D]. </description> </method> - <method name="Transform" qualifiers="constructor"> - <return type="Transform"> + <method name="Transform3D" qualifiers="constructor"> + <return type="Transform3D"> </return> <argument index="0" name="basis" type="Basis"> </argument> <argument index="1" name="origin" type="Vector3"> </argument> <description> - Constructs a Transform from a [Basis] and [Vector3]. + Constructs a Transform3D from a [Basis] and [Vector3]. </description> </method> - <method name="Transform" qualifiers="constructor"> - <return type="Transform"> + <method name="Transform3D" qualifiers="constructor"> + <return type="Transform3D"> </return> <argument index="0" name="x_axis" type="Vector3"> </argument> @@ -55,29 +55,29 @@ <argument index="3" name="origin" type="Vector3"> </argument> <description> - Constructs a Transform from four [Vector3] values (matrix columns). Each axis corresponds to local basis vectors (some of which may be scaled). + Constructs a Transform3D from four [Vector3] values (matrix columns). Each axis corresponds to local basis vectors (some of which may be scaled). </description> </method> <method name="affine_inverse" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Returns the inverse of the transform, under the assumption that the transformation is composed of rotation, scaling and translation. </description> </method> <method name="interpolate_with" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> - <argument index="0" name="xform" type="Transform"> + <argument index="0" name="xform" type="Transform3D"> </argument> <argument index="1" name="weight" type="float"> </argument> <description> - Interpolates the transform to other Transform by weight amount (on the range of 0.0 to 1.0). + Interpolates the transform to other Transform3D by weight amount (on the range of 0.0 to 1.0). </description> </method> <method name="inverse" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling). @@ -86,14 +86,14 @@ <method name="is_equal_approx" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="xform" type="Transform"> + <argument index="0" name="xform" type="Transform3D"> </argument> <description> Returns [code]true[/code] if this transform and [code]transform[/code] are approximately equal, by calling [code]is_equal_approx[/code] on each component. </description> </method> <method name="looking_at" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="target" type="Vector3"> </argument> @@ -108,7 +108,7 @@ <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> @@ -122,9 +122,9 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Transform"> + <return type="Transform3D"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> @@ -148,20 +148,20 @@ <method name="operator ==" qualifiers="operator"> <return type="bool"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> </method> <method name="orthonormalized" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors. </description> </method> <method name="rotated" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="axis" type="Vector3"> </argument> @@ -172,7 +172,7 @@ </description> </method> <method name="scaled" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="scale" type="Vector3"> </argument> @@ -181,7 +181,7 @@ </description> </method> <method name="translated" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="offset" type="Vector3"> </argument> @@ -200,17 +200,17 @@ </member> </members> <constants> - <constant name="IDENTITY" value="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> - [Transform] with no translation, rotation or scaling applied. When applied to other data structures, [constant IDENTITY] performs no transformation. + <constant name="IDENTITY" value="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform3D] with no translation, rotation or scaling applied. When applied to other data structures, [constant IDENTITY] performs no transformation. </constant> - <constant name="FLIP_X" value="Transform( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> - [Transform] with mirroring applied perpendicular to the YZ plane. + <constant name="FLIP_X" value="Transform3D( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform3D] with mirroring applied perpendicular to the YZ plane. </constant> - <constant name="FLIP_Y" value="Transform( 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0 )"> - [Transform] with mirroring applied perpendicular to the XZ plane. + <constant name="FLIP_Y" value="Transform3D( 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform3D] with mirroring applied perpendicular to the XZ plane. </constant> - <constant name="FLIP_Z" value="Transform( 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0 )"> - [Transform] with mirroring applied perpendicular to the XY plane. + <constant name="FLIP_Z" value="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0 )"> + [Transform3D] with mirroring applied perpendicular to the XY plane. </constant> </constants> </class> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 94d4b1a903..1390a5e45b 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -110,13 +110,15 @@ Returns the vector with all components rounded up (towards positive infinity). </description> </method> - <method name="clamped" qualifiers="const"> + <method name="clamp" qualifiers="const"> <return type="Vector2"> </return> - <argument index="0" name="length" type="float"> + <argument index="0" name="min" type="Vector2"> + </argument> + <argument index="1" name="max" type="Vector2"> </argument> <description> - Returns the vector with a maximum length by limiting its length to [code]length[/code]. + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. </description> </method> <method name="cross" qualifiers="const"> @@ -232,6 +234,15 @@ Returns the result of the linear interpolation between this vector and [code]to[/code] by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. </description> </method> + <method name="limit_length" qualifiers="const"> + <return type="Vector2"> + </return> + <argument index="0" name="length" type="float" default="1.0"> + </argument> + <description> + Returns the vector with a maximum length by limiting its length to [code]length[/code]. + </description> + </method> <method name="move_toward" qualifiers="const"> <return type="Vector2"> </return> diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml index b38b968ba3..6efb52b712 100644 --- a/doc/classes/Vector2i.xml +++ b/doc/classes/Vector2i.xml @@ -64,6 +64,17 @@ Returns the ratio of [member x] to [member y]. </description> </method> + <method name="clamp" qualifiers="const"> + <return type="Vector2i"> + </return> + <argument index="0" name="min" type="Vector2i"> + </argument> + <argument index="1" name="max" type="Vector2i"> + </argument> + <description> + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> <method name="operator !=" qualifiers="operator"> <return type="bool"> </return> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 0a86369506..b6effd441b 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -87,6 +87,17 @@ Returns a new vector with all components rounded up (towards positive infinity). </description> </method> + <method name="clamp" qualifiers="const"> + <return type="Vector3"> + </return> + <argument index="0" name="min" type="Vector3"> + </argument> + <argument index="1" name="max" type="Vector3"> + </argument> + <description> + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> <method name="cross" qualifiers="const"> <return type="Vector3"> </return> @@ -207,6 +218,15 @@ Returns the result of the linear interpolation between this vector and [code]to[/code] by amount [code]weight[/code]. [code]weight[/code] is on the range of 0.0 to 1.0, representing the amount of interpolation. </description> </method> + <method name="limit_length" qualifiers="const"> + <return type="Vector3"> + </return> + <argument index="0" name="length" type="float" default="1.0"> + </argument> + <description> + Returns the vector with a maximum length by limiting its length to [code]length[/code]. + </description> + </method> <method name="max_axis" qualifiers="const"> <return type="int"> </return> @@ -266,7 +286,7 @@ <method name="operator *" qualifiers="operator"> <return type="Vector3"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> </description> @@ -274,7 +294,7 @@ <method name="operator *" qualifiers="operator"> <return type="Vector3"> </return> - <argument index="0" name="right" type="Transform"> + <argument index="0" name="right" type="Transform3D"> </argument> <description> </description> diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml index ea5945f5b7..6e8a34b692 100644 --- a/doc/classes/Vector3i.xml +++ b/doc/classes/Vector3i.xml @@ -58,6 +58,17 @@ <description> </description> </method> + <method name="clamp" qualifiers="const"> + <return type="Vector3i"> + </return> + <argument index="0" name="min" type="Vector3i"> + </argument> + <argument index="1" name="max" type="Vector3i"> + </argument> + <description> + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> <method name="max_axis" qualifiers="const"> <return type="int"> </return> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 1c33274cb0..7f05b14765 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -382,14 +382,14 @@ </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 name="DEBUG_DRAW_VOXEL_GI_ALBEDO" value="6" enum="DebugDraw"> + Objects are displayed with only the albedo value from [VoxelGI]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 name="DEBUG_DRAW_VOXEL_GI_LIGHTING" value="7" enum="DebugDraw"> + Objects are displayed with only the lighting value from [VoxelGI]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 name="DEBUG_DRAW_VOXEL_GI_EMISSION" value="8" enum="DebugDraw"> + Objects are displayed with only the emission color from [VoxelGI]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]. diff --git a/doc/classes/VisualInstance3D.xml b/doc/classes/VisualInstance3D.xml index 01d569d9c8..2a12254b71 100644 --- a/doc/classes/VisualInstance3D.xml +++ b/doc/classes/VisualInstance3D.xml @@ -44,7 +44,7 @@ </return> <description> Returns the transformed [AABB] (also known as the bounding box) for this [VisualInstance3D]. - Transformed in this case means the [AABB] plus the position, rotation, and scale of the [Node3D]'s [Transform]. See also [method get_aabb]. + Transformed in this case means the [AABB] plus the position, rotation, and scale of the [Node3D]'s [Transform3D]. See also [method get_aabb]. </description> </method> <method name="set_base"> diff --git a/doc/classes/VisualShader.xml b/doc/classes/VisualShader.xml index ff00a848b9..775ac88eff 100644 --- a/doc/classes/VisualShader.xml +++ b/doc/classes/VisualShader.xml @@ -222,15 +222,19 @@ <constant name="TYPE_LIGHT" value="2" enum="Type"> A shader for light calculations. </constant> - <constant name="TYPE_EMIT" value="3" enum="Type"> + <constant name="TYPE_START" value="3" enum="Type"> </constant> <constant name="TYPE_PROCESS" value="4" enum="Type"> </constant> - <constant name="TYPE_END" value="5" enum="Type"> + <constant name="TYPE_COLLIDE" value="5" enum="Type"> </constant> - <constant name="TYPE_SKY" value="6" enum="Type"> + <constant name="TYPE_START_CUSTOM" value="6" enum="Type"> </constant> - <constant name="TYPE_MAX" value="7" enum="Type"> + <constant name="TYPE_PROCESS_CUSTOM" value="7" enum="Type"> + </constant> + <constant name="TYPE_SKY" value="8" enum="Type"> + </constant> + <constant name="TYPE_MAX" value="9" enum="Type"> Represents the size of the [enum Type] enum. </constant> <constant name="NODE_ID_INVALID" value="-1"> diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml index 6327ab534f..9a74f2322e 100644 --- a/doc/classes/VisualShaderNode.xml +++ b/doc/classes/VisualShaderNode.xml @@ -9,6 +9,13 @@ <link title="VisualShaders">https://docs.godotengine.org/en/latest/tutorials/shading/visual_shaders.html</link> </tutorials> <methods> + <method name="clear_default_input_values"> + <return type="void"> + </return> + <description> + Clears the default input ports value. + </description> + </method> <method name="get_default_input_values" qualifiers="const"> <return type="Array"> </return> @@ -25,6 +32,15 @@ Returns the default value of the input [code]port[/code]. </description> </method> + <method name="remove_input_port_default_value"> + <return type="void"> + </return> + <argument index="0" name="port" type="int"> + </argument> + <description> + Removes the default value of the input [code]port[/code]. + </description> + </method> <method name="set_default_input_values"> <return type="void"> </return> diff --git a/doc/classes/VisualShaderNodeDeterminant.xml b/doc/classes/VisualShaderNodeDeterminant.xml index 6b042f6172..06b05addfa 100644 --- a/doc/classes/VisualShaderNodeDeterminant.xml +++ b/doc/classes/VisualShaderNodeDeterminant.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeDeterminant" inherits="VisualShaderNode" version="4.0"> <brief_description> - Calculates the determinant of a [Transform] within the visual shader graph. + Calculates the determinant of a [Transform3D] within the visual shader graph. </brief_description> <description> Translates to [code]determinant(x)[/code] in the shader language. diff --git a/doc/classes/VisualShaderNodeParticleAccelerator.xml b/doc/classes/VisualShaderNodeParticleAccelerator.xml new file mode 100644 index 0000000000..82aae1df63 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleAccelerator.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleAccelerator" inherits="VisualShaderNodeOutput" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="VisualShaderNodeParticleAccelerator.Mode" default="0"> + </member> + </members> + <constants> + <constant name="MODE_LINEAR" value="0" enum="Mode"> + </constant> + <constant name="MODE_RADIAL" value="1" enum="Mode"> + </constant> + <constant name="MODE_TANGENTIAL" value="2" enum="Mode"> + </constant> + <constant name="MODE_MAX" value="3" enum="Mode"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleBoxEmitter.xml b/doc/classes/VisualShaderNodeParticleBoxEmitter.xml new file mode 100644 index 0000000000..af33b285d2 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleBoxEmitter.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleBoxEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleConeVelocity.xml b/doc/classes/VisualShaderNodeParticleConeVelocity.xml new file mode 100644 index 0000000000..7a40c2a7d0 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleConeVelocity.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleConeVelocity" inherits="VisualShaderNode" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleEmit.xml b/doc/classes/VisualShaderNodeParticleEmit.xml new file mode 100644 index 0000000000..120b12d643 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleEmit.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleEmit" inherits="VisualShaderNode" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="flags" type="int" setter="set_flags" getter="get_flags" enum="VisualShaderNodeParticleEmit.EmitFlags" default="31"> + </member> + </members> + <constants> + <constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags"> + </constant> + <constant name="EMIT_FLAG_ROT_SCALE" value="2" enum="EmitFlags"> + </constant> + <constant name="EMIT_FLAG_VELOCITY" value="4" enum="EmitFlags"> + </constant> + <constant name="EMIT_FLAG_COLOR" value="8" enum="EmitFlags"> + </constant> + <constant name="EMIT_FLAG_CUSTOM" value="16" enum="EmitFlags"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleEmitter.xml b/doc/classes/VisualShaderNodeParticleEmitter.xml new file mode 100644 index 0000000000..3a25fc1c7f --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleEmitter.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleEmitter" inherits="VisualShaderNode" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleMultiplyByAxisAngle.xml b/doc/classes/VisualShaderNodeParticleMultiplyByAxisAngle.xml new file mode 100644 index 0000000000..89a53699c9 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleMultiplyByAxisAngle.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleMultiplyByAxisAngle" inherits="VisualShaderNode" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="degrees_mode" type="bool" setter="set_degrees_mode" getter="is_degrees_mode" default="true"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleOutput.xml b/doc/classes/VisualShaderNodeParticleOutput.xml new file mode 100644 index 0000000000..c8fc66f2ff --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleOutput.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleOutput" inherits="VisualShaderNodeOutput" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleRandomness.xml b/doc/classes/VisualShaderNodeParticleRandomness.xml new file mode 100644 index 0000000000..f19723a663 --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleRandomness.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleRandomness" inherits="VisualShaderNode" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeParticleRandomness.OpType" default="0"> + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + </constant> + <constant name="OP_TYPE_MAX" value="2" enum="OpType"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleRingEmitter.xml b/doc/classes/VisualShaderNodeParticleRingEmitter.xml new file mode 100644 index 0000000000..ee3fbe7faf --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleRingEmitter.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleRingEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeParticleSphereEmitter.xml b/doc/classes/VisualShaderNodeParticleSphereEmitter.xml new file mode 100644 index 0000000000..d43ac518cf --- /dev/null +++ b/doc/classes/VisualShaderNodeParticleSphereEmitter.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeParticleSphereEmitter" inherits="VisualShaderNodeParticleEmitter" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTransformCompose.xml b/doc/classes/VisualShaderNodeTransformCompose.xml index 41762b0099..b82ce9bdd8 100644 --- a/doc/classes/VisualShaderNodeTransformCompose.xml +++ b/doc/classes/VisualShaderNodeTransformCompose.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformCompose" inherits="VisualShaderNode" version="4.0"> <brief_description> - Composes a [Transform] from four [Vector3]s within the visual shader graph. + Composes a [Transform3D] from four [Vector3]s within the visual shader graph. </brief_description> <description> Creates a 4x4 transform matrix using four vectors of type [code]vec3[/code]. Each vector is one row in the matrix and the last column is a [code]vec4(0, 0, 0, 1)[/code]. diff --git a/doc/classes/VisualShaderNodeTransformConstant.xml b/doc/classes/VisualShaderNodeTransformConstant.xml index b8f054e914..550ed829c9 100644 --- a/doc/classes/VisualShaderNodeTransformConstant.xml +++ b/doc/classes/VisualShaderNodeTransformConstant.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNodeConstant" version="4.0"> <brief_description> - A [Transform] constant for use within the visual shader graph. + A [Transform3D] constant for use within the visual shader graph. </brief_description> <description> - A constant [Transform], which can be used as an input node. + A constant [Transform3D], which can be used as an input node. </description> <tutorials> </tutorials> <methods> </methods> <members> - <member name="constant" type="Transform" setter="set_constant" getter="get_constant" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> - A [Transform] constant which represents the state of this node. + <member name="constant" type="Transform3D" setter="set_constant" getter="get_constant" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + A [Transform3D] constant which represents the state of this node. </member> </members> <constants> diff --git a/doc/classes/VisualShaderNodeTransformDecompose.xml b/doc/classes/VisualShaderNodeTransformDecompose.xml index c8d893db00..b815efc67a 100644 --- a/doc/classes/VisualShaderNodeTransformDecompose.xml +++ b/doc/classes/VisualShaderNodeTransformDecompose.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformDecompose" inherits="VisualShaderNode" version="4.0"> <brief_description> - Decomposes a [Transform] into four [Vector3]s within the visual shader graph. + Decomposes a [Transform3D] into four [Vector3]s within the visual shader graph. </brief_description> <description> Takes a 4x4 transform matrix and decomposes it into four [code]vec3[/code] values, one from each row of the matrix. diff --git a/doc/classes/VisualShaderNodeTransformFunc.xml b/doc/classes/VisualShaderNodeTransformFunc.xml index d0b5c5129d..41a58e1458 100644 --- a/doc/classes/VisualShaderNodeTransformFunc.xml +++ b/doc/classes/VisualShaderNodeTransformFunc.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformFunc" inherits="VisualShaderNode" version="4.0"> <brief_description> - Computes a [Transform] function within the visual shader graph. + Computes a [Transform3D] function within the visual shader graph. </brief_description> <description> - Computes an inverse or transpose function on the provided [Transform]. + Computes an inverse or transpose function on the provided [Transform3D]. </description> <tutorials> </tutorials> @@ -17,10 +17,10 @@ </members> <constants> <constant name="FUNC_INVERSE" value="0" enum="Function"> - Perform the inverse operation on the [Transform] matrix. + Perform the inverse operation on the [Transform3D] matrix. </constant> <constant name="FUNC_TRANSPOSE" value="1" enum="Function"> - Perform the transpose operation on the [Transform] matrix. + Perform the transpose operation on the [Transform3D] matrix. </constant> </constants> </class> diff --git a/doc/classes/VisualShaderNodeTransformMult.xml b/doc/classes/VisualShaderNodeTransformMult.xml index 02b6e0cd1c..f26f60a1f3 100644 --- a/doc/classes/VisualShaderNodeTransformMult.xml +++ b/doc/classes/VisualShaderNodeTransformMult.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformMult" inherits="VisualShaderNode" version="4.0"> <brief_description> - Multiplies [Transform] by [Transform] within the visual shader graph. + Multiplies [Transform3D] by [Transform3D] within the visual shader graph. </brief_description> <description> A multiplication operation on two transforms (4x4 matrices), with support for different multiplication operators. diff --git a/doc/classes/VisualShaderNodeTransformUniform.xml b/doc/classes/VisualShaderNodeTransformUniform.xml index ff6246618d..1f1cc4b630 100644 --- a/doc/classes/VisualShaderNodeTransformUniform.xml +++ b/doc/classes/VisualShaderNodeTransformUniform.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformUniform" inherits="VisualShaderNodeUniform" version="4.0"> <brief_description> - A [Transform] uniform for use within the visual shader graph. + A [Transform3D] uniform for use within the visual shader graph. </brief_description> <description> Translated to [code]uniform mat4[/code] in the shader language. @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="default_value" type="Transform" setter="set_default_value" getter="get_default_value" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <member name="default_value" type="Transform3D" setter="set_default_value" getter="get_default_value" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> A default value to be assigned within the shader. </member> <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false"> diff --git a/doc/classes/VisualShaderNodeTransformVecMult.xml b/doc/classes/VisualShaderNodeTransformVecMult.xml index 3d5f87f727..2c9c115d9c 100644 --- a/doc/classes/VisualShaderNodeTransformVecMult.xml +++ b/doc/classes/VisualShaderNodeTransformVecMult.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeTransformVecMult" inherits="VisualShaderNode" version="4.0"> <brief_description> - Multiplies a [Transform] and a [Vector3] within the visual shader graph. + Multiplies a [Transform3D] and a [Vector3] within the visual shader graph. </brief_description> <description> A multiplication operation on a transform (4x4 matrix) and a vector, with support for different multiplication operators. diff --git a/doc/classes/VisualShaderNodeUVFunc.xml b/doc/classes/VisualShaderNodeUVFunc.xml new file mode 100644 index 0000000000..042644feb0 --- /dev/null +++ b/doc/classes/VisualShaderNodeUVFunc.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeUVFunc" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Contains functions to modify texture coordinates ([code]uv[/code]) to be used within the visual shader graph. + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeUVFunc.Function" default="0"> + A function to be applied to the texture coordinates. See [enum Function] for options. + </member> + </members> + <constants> + <constant name="FUNC_PANNING" value="0" enum="Function"> + Translates [code]uv[/code] by using [code]scale[/code] and [code]offset[/code] values using the following formula: [code]uv = uv + offset * scale[/code]. [code]uv[/code] port is connected to [code]UV[/code] built-in by default. + </constant> + <constant name="FUNC_SCALING" value="1" enum="Function"> + Scales [code]uv[/uv] by using [code]scale[/code] and [code]pivot[/code] values using the following formula: [code]uv = (uv - pivot) * scale + pivot[/code]. [code]uv[/code] port is connected to [code]UV[/code] built-in by default. + </constant> + <constant name="FUNC_MAX" value="2" enum="Function"> + Represents the size of the [enum Function] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/GIProbe.xml b/doc/classes/VoxelGI.xml index 4f56d1ad3e..fa5035349e 100644 --- a/doc/classes/GIProbe.xml +++ b/doc/classes/VoxelGI.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GIProbe" inherits="VisualInstance3D" version="4.0"> +<class name="VoxelGI" inherits="VisualInstance3D" version="4.0"> <brief_description> Real-time global illumination (GI) probe. </brief_description> <description> - [GIProbe]s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [GIProbe]s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked. - Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/global_illumination/gi_probes/quality]. + [VoxelGI]s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [VoxelGI]s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked. + Having [VoxelGI]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/global_illumination/voxel_gi/quality]. [b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh. </description> <tutorials> - <link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link> + <link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/voxel_gi.html</link> <link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link> </tutorials> <methods> @@ -21,7 +21,7 @@ <argument index="1" name="create_visual_debug" type="bool" default="false"> </argument> <description> - Bakes the effect from all [GeometryInstance3D]s marked with [constant GeometryInstance3D.GI_MODE_BAKED] and [Light3D]s marked with either [constant Light3D.BAKE_DYNAMIC] or [constant Light3D.BAKE_STATIC]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [GIProbe]'s data and debug any issues that may be occurring. + Bakes the effect from all [GeometryInstance3D]s marked with [constant GeometryInstance3D.GI_MODE_BAKED] and [Light3D]s marked with either [constant Light3D.BAKE_DYNAMIC] or [constant Light3D.BAKE_STATIC]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [VoxelGI]'s data and debug any issues that may be occurring. </description> </method> <method name="debug_bake"> @@ -33,14 +33,14 @@ </method> </methods> <members> - <member name="data" type="GIProbeData" setter="set_probe_data" getter="get_probe_data"> - The [GIProbeData] resource that holds the data for this [GIProbe]. + <member name="data" type="VoxelGIData" setter="set_probe_data" getter="get_probe_data"> + The [VoxelGIData] resource that holds the data for this [VoxelGI]. </member> <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 10, 10, 10 )"> - The size of the area covered by the [GIProbe]. If you make the extents larger without increasing the subdivisions with [member subdiv], the size of each cell will increase and result in lower detailed lighting. + The size of the area covered by the [VoxelGI]. If you make the extents larger without increasing the subdivisions with [member subdiv], the size of each cell will increase and result in lower detailed lighting. </member> - <member name="subdiv" type="int" setter="set_subdiv" getter="get_subdiv" enum="GIProbe.Subdiv" default="1"> - Number of times to subdivide the grid that the [GIProbe] operates on. A higher number results in finer detail and thus higher visual quality, while lower numbers result in better performance. + <member name="subdiv" type="int" setter="set_subdiv" getter="get_subdiv" enum="VoxelGI.Subdiv" default="1"> + Number of times to subdivide the grid that the [VoxelGI] operates on. A higher number results in finer detail and thus higher visual quality, while lower numbers result in better performance. </member> </members> <constants> diff --git a/doc/classes/GIProbeData.xml b/doc/classes/VoxelGIData.xml index 693df8f819..88a0411e2b 100644 --- a/doc/classes/GIProbeData.xml +++ b/doc/classes/VoxelGIData.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GIProbeData" inherits="Resource" version="4.0"> +<class name="VoxelGIData" inherits="Resource" version="4.0"> <brief_description> </brief_description> <description> @@ -11,7 +11,7 @@ <method name="allocate"> <return type="void"> </return> - <argument index="0" name="to_cell_xform" type="Transform"> + <argument index="0" name="to_cell_xform" type="Transform3D"> </argument> <argument index="1" name="aabb" type="AABB"> </argument> @@ -59,7 +59,7 @@ </description> </method> <method name="get_to_cell_xform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> </description> diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index 5274d952fd..2cf8e1d6f5 100644 --- a/doc/classes/XRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -69,7 +69,7 @@ </description> </method> <method name="get_transform" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <argument index="0" name="adjust_by_reference_frame" type="bool"> </argument> diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml index d0edf91fed..8284fa4a89 100644 --- a/doc/classes/XRServer.xml +++ b/doc/classes/XRServer.xml @@ -63,7 +63,7 @@ </description> </method> <method name="get_hmd_transform"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Returns the primary interface's transformation. @@ -114,7 +114,7 @@ </description> </method> <method name="get_reference_frame" qualifiers="const"> - <return type="Transform"> + <return type="Transform3D"> </return> <description> Returns the reference frame transform. Mostly used internally and exposed for GDNative build interfaces. diff --git a/doc/classes/YSort.xml b/doc/classes/YSort.xml deleted file mode 100644 index 4ef6a4b4ec..0000000000 --- a/doc/classes/YSort.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="YSort" inherits="Node2D" version="4.0"> - <brief_description> - Sort all child nodes based on their Y positions. - </brief_description> - <description> - Sort all child nodes based on their Y positions. The child node must inherit from [CanvasItem] for it to be sorted. Nodes that have a higher Y position will be drawn later, so they will appear on top of nodes that have a lower Y position. - Nesting of YSort nodes is possible. Children YSort nodes will be sorted in the same space as the parent YSort, allowing to better organize a scene or divide it in multiple ones, yet keep the unique sorting. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <members> - <member name="sort_enabled" type="bool" setter="set_sort_enabled" getter="is_sort_enabled" default="true"> - If [code]true[/code], child nodes are sorted, otherwise sorting is disabled. - </member> - </members> - <constants> - </constants> -</class> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index 11f6d91b05..f75c130039 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -113,12 +113,12 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> - Multiplies each component of the [Quat] by the given [float]. + Multiplies each component of the [Quaternion] by the given [float]. </description> </method> <method name="operator *" qualifiers="operator"> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index 119cdf8eeb..b0ad963998 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -183,9 +183,9 @@ </description> </method> <method name="operator *" qualifiers="operator"> - <return type="Quat"> + <return type="Quaternion"> </return> - <argument index="0" name="right" type="Quat"> + <argument index="0" name="right" type="Quaternion"> </argument> <description> Multiplies each component of the quaternion by the given integer. diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 0f8f2260f2..5e2431d44e 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -35,6 +35,10 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#ifdef ALSAMIDI_ENABLED +#include "drivers/alsa/asound-so_wrap.h" +#endif + void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; @@ -272,6 +276,10 @@ Error AudioDriverPulseAudio::init() { #else int dylibloader_verbose = 0; #endif +#ifdef ALSAMIDI_ENABLED + // If using PulseAudio with ALSA MIDI, we need to initialize ALSA as well + initialize_asound(dylibloader_verbose); +#endif if (initialize_pulse(dylibloader_verbose)) { return ERR_CANT_OPEN; } diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index ec23df62d0..6ea55219bb 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -264,7 +264,7 @@ void FileAccessUnix::store_8(uint8_t p_dest) { void FileAccessUnix::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); - ERR_FAIL_COND(!p_src); + ERR_FAIL_COND(!p_src && p_length > 0); ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length); } diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index 222aef998c..efeaf32ff7 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -466,7 +466,7 @@ Error NetSocketPosix::poll(PollType p_type, int p_timeout) const { FD_ZERO(&ex); FD_SET(_sock, &ex); struct timeval timeout = { p_timeout / 1000, (p_timeout % 1000) * 1000 }; - // For blocking operation, pass nullptr timeout pointer to select. + // For blocking operation, pass nullptr timeout pointer to select. struct timeval *tp = nullptr; if (p_timeout >= 0) { // If timeout is non-negative, we want to specify the timeout instead. diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 43b2a24172..dc92e04a43 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -3280,7 +3280,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF // For each UNDEFINED, assume the prior use was a *read*, as we'd be discarding the output of a write // Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution synchronization vs. - // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that + // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that // stage switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) { case INITIAL_ACTION_CLEAR_REGION: diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 1f46b44f5e..d6deda7b5d 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -294,6 +294,7 @@ void FileAccessWindows::store_8(uint8_t p_dest) { void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND(!f); + ERR_FAIL_COND(!p_src && p_length > 0); if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == READ) { if (last_error != ERR_FILE_EOF) { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 3620fda4f8..fde75e0f0c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -165,7 +165,7 @@ public: } switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Dictionary d_old = animation->track_get_key_value(track, key); Dictionary d_new = d_old.duplicate(); d_new[p_name] = p_value; @@ -412,7 +412,7 @@ public: } switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Dictionary d = animation->track_get_key_value(track, key); ERR_FAIL_COND_V(!d.has(name), false); r_ret = d[p_name]; @@ -523,9 +523,9 @@ public: } switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "location")); - p_list->push_back(PropertyInfo(Variant::QUAT, "rotation")); + p_list->push_back(PropertyInfo(Variant::QUATERNION, "rotation")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale")); } break; @@ -781,7 +781,7 @@ public: } switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Dictionary d_old = animation->track_get_key_value(track, key); Dictionary d_new = d_old.duplicate(); d_new[p_name] = p_value; @@ -1012,7 +1012,7 @@ public: } switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Dictionary d = animation->track_get_key_value(track, key); ERR_FAIL_COND_V(!d.has(name), false); r_ret = d[p_name]; @@ -1162,9 +1162,9 @@ public: if (same_track_type) { switch (animation->track_get_type(first_track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "location")); - p_list->push_back(PropertyInfo(Variant::QUAT, "rotation")); + p_list->push_back(PropertyInfo(Variant::QUATERNION, "rotation")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale")); } break; case Animation::TYPE_VALUE: { @@ -2007,7 +2007,7 @@ void AnimationTrackEdit::_notification(int p_what) { interp_mode_rect.position.y = int(get_size().height - icon->get_height()) / 2; interp_mode_rect.size = icon->get_size(); - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM3D) { draw_texture(icon, interp_mode_rect.position); } //make it easier to click @@ -2017,7 +2017,7 @@ void AnimationTrackEdit::_notification(int p_what) { ofs += icon->get_width() + hsep; interp_mode_rect.size.x += hsep; - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM3D) { draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); interp_mode_rect.size.x += down_icon->get_width(); } else { @@ -2040,7 +2040,7 @@ void AnimationTrackEdit::_notification(int p_what) { loop_mode_rect.position.y = int(get_size().height - icon->get_height()) / 2; loop_mode_rect.size = icon->get_size(); - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM3D) { draw_texture(icon, loop_mode_rect.position); } @@ -2050,7 +2050,7 @@ void AnimationTrackEdit::_notification(int p_what) { ofs += icon->get_width() + hsep; loop_mode_rect.size.x += hsep; - if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_TRANSFORM3D) { draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); loop_mode_rect.size.x += down_icon->get_width(); } else { @@ -2441,7 +2441,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { if (key_idx != -1) { String text = TTR("Time (s): ") + rtos(animation->track_get_key_time(track, key_idx)) + "\n"; switch (animation->track_get_type(track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Dictionary d = animation->track_get_key_value(track, key_idx); if (d.has("location")) { text += "Pos: " + String(d["location"]) + "\n"; @@ -3310,7 +3310,7 @@ static bool track_type_is_resettable(Animation::TrackType p_type) { [[fallthrough]]; case Animation::TYPE_BEZIER: [[fallthrough]]; - case Animation::TYPE_TRANSFORM: + case Animation::TYPE_TRANSFORM3D: return true; default: return false; @@ -3376,7 +3376,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) { case Variant::FLOAT: case Variant::VECTOR2: case Variant::VECTOR3: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::PLANE: case Variant::COLOR: { // Valid. @@ -3459,7 +3459,7 @@ void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_bezi insert_queue = false; } -void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_sub, const Transform &p_xform) { +void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_sub, const Transform3D &p_xform) { if (!keying) { return; } @@ -3479,7 +3479,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_ int track_idx = -1; for (int i = 0; i < animation->get_track_count(); i++) { - if (animation->track_get_type(i) != Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(i) != Animation::TYPE_TRANSFORM3D) { continue; } if (animation->track_get_path(i) != np) { @@ -3496,7 +3496,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_ id.path = np; id.track_idx = track_idx; id.value = p_xform; - id.type = Animation::TYPE_TRANSFORM; + id.type = Animation::TYPE_TRANSFORM3D; id.query = "node '" + p_node->get_name() + "'"; id.advance = false; @@ -3845,7 +3845,7 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool subindices.push_back(":y"); subindices.push_back(":z"); } break; - case Variant::QUAT: { + case Variant::QUATERNION: { subindices.push_back(":x"); subindices.push_back(":y"); subindices.push_back(":z"); @@ -3911,11 +3911,11 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD h.type == Variant::RECT2 || h.type == Variant::VECTOR3 || h.type == Variant::AABB || - h.type == Variant::QUAT || + h.type == Variant::QUATERNION || h.type == Variant::COLOR || h.type == Variant::PLANE || h.type == Variant::TRANSFORM2D || - h.type == Variant::TRANSFORM) { + h.type == Variant::TRANSFORM3D) { update_mode = Animation::UPDATE_CONTINUOUS; } @@ -3945,12 +3945,12 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD value = p_id.value; } break; - case Animation::TYPE_TRANSFORM: { - Transform tr = p_id.value; + case Animation::TYPE_TRANSFORM3D: { + Transform3D tr = p_id.value; Dictionary d; d["location"] = tr.origin; d["scale"] = tr.basis.get_scale(); - d["rotation"] = Quat(tr.basis); + d["rotation"] = Quaternion(tr.basis); value = d; } break; case Animation::TYPE_BEZIER: { @@ -4368,8 +4368,8 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { ERR_FAIL_COND(!node); NodePath path_to = root->get_path_to(node); - if (adding_track_type == Animation::TYPE_TRANSFORM && !node->is_class("Node3D")) { - EditorNode::get_singleton()->show_warning(TTR("Transform tracks only apply to 3D-based nodes.")); + if (adding_track_type == Animation::TYPE_TRANSFORM3D && !node->is_class("Node3D")) { + EditorNode::get_singleton()->show_warning(TTR("Transform3D tracks only apply to 3D-based nodes.")); return; } @@ -4379,7 +4379,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { prop_selector->set_type_filter(Vector<Variant::Type>()); prop_selector->select_property_from_instance(node); } break; - case Animation::TYPE_TRANSFORM: + case Animation::TYPE_TRANSFORM3D: case Animation::TYPE_METHOD: { undo_redo->create_action(TTR("Add Track")); undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type); @@ -4394,7 +4394,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) { filter.push_back(Variant::FLOAT); filter.push_back(Variant::VECTOR2); filter.push_back(Variant::VECTOR3); - filter.push_back(Variant::QUAT); + filter.push_back(Variant::QUATERNION); filter.push_back(Variant::PLANE); filter.push_back(Variant::COLOR); @@ -4464,11 +4464,11 @@ void AnimationTrackEditor::_new_track_property_selected(String p_name) { h.type == Variant::RECT2 || h.type == Variant::VECTOR3 || h.type == Variant::AABB || - h.type == Variant::QUAT || + h.type == Variant::QUATERNION || h.type == Variant::COLOR || h.type == Variant::PLANE || h.type == Variant::TRANSFORM2D || - h.type == Variant::TRANSFORM) { + h.type == Variant::TRANSFORM3D) { update_mode = Animation::UPDATE_CONTINUOUS; } @@ -4548,7 +4548,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { } switch (animation->track_get_type(p_track)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { if (!root->has_node(animation->track_get_path(p_track))) { EditorNode::get_singleton()->show_warning(TTR("Track path is invalid, so can't add a key.")); return; @@ -4560,11 +4560,11 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) { return; } - Transform xf = base->get_transform(); + Transform3D xf = base->get_transform(); Vector3 loc = xf.get_origin(); Vector3 scale = xf.basis.get_scale_local(); - Quat rot = xf.basis; + Quaternion rot = xf.basis; undo_redo->create_action(TTR("Add Transform Track Key")); undo_redo->add_do_method(animation.ptr(), "transform_track_insert_key", p_track, p_ofs, loc, rot, scale); @@ -5182,7 +5182,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { } switch (animation->track_get_type(i)) { - case Animation::TYPE_TRANSFORM: + case Animation::TYPE_TRANSFORM3D: text += " (Transform)"; break; case Animation::TYPE_METHOD: diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 8befc830fa..756eb4acb6 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -526,7 +526,7 @@ public: void set_anim_pos(float p_pos); void insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists = false); void insert_value_key(const String &p_property, const Variant &p_value, bool p_advance); - void insert_transform_key(Node3D *p_node, const String &p_sub, const Transform &p_xform); + void insert_transform_key(Node3D *p_node, const String &p_sub, const Transform3D &p_xform); void show_select_node_warning(bool p_show); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index de2be710c5..3c0651f019 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -203,8 +203,8 @@ void ConnectDialog::_add_bind() { case Variant::PLANE: value = Plane(); break; - case Variant::QUAT: - value = Quat(); + case Variant::QUATERNION: + value = Quaternion(); break; case Variant::AABB: value = AABB(); @@ -212,8 +212,8 @@ void ConnectDialog::_add_bind() { case Variant::BASIS: value = Basis(); break; - case Variant::TRANSFORM: - value = Transform(); + case Variant::TRANSFORM3D: + value = Transform3D(); break; case Variant::COLOR: value = Color(); @@ -443,10 +443,10 @@ ConnectDialog::ConnectDialog() { type_list->add_item("Rect2", Variant::RECT2); type_list->add_item("Vector3", Variant::VECTOR3); type_list->add_item("Plane", Variant::PLANE); - type_list->add_item("Quat", Variant::QUAT); + type_list->add_item("Quaternion", Variant::QUATERNION); type_list->add_item("AABB", Variant::AABB); type_list->add_item("Basis", Variant::BASIS); - type_list->add_item("Transform", Variant::TRANSFORM); + type_list->add_item("Transform", Variant::TRANSFORM3D); type_list->add_item("Color", Variant::COLOR); type_list->select(0); diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 7527514dca..b8504ad02a 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -141,7 +141,7 @@ EditorAbout::EditorAbout() { version_btn = memnew(LinkButton); String hash = String(VERSION_HASH); if (hash.length() != 0) { - hash = "." + hash.left(9); + hash = " " + vformat("[%s]", hash.left(9)); } version_btn->set_text(VERSION_FULL_NAME + hash); // Set the text to copy in metadata as it slightly differs from the button's text. diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 9dcd550f5c..e7937a8e3c 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -137,7 +137,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { extension_guess["atlastex"] = tree->get_theme_icon("AtlasTexture", "EditorIcons"); extension_guess["scn"] = tree->get_theme_icon("PackedScene", "EditorIcons"); extension_guess["tscn"] = tree->get_theme_icon("PackedScene", "EditorIcons"); - extension_guess["shader"] = tree->get_theme_icon("Shader", "EditorIcons"); + extension_guess["gdshader"] = tree->get_theme_icon("Shader", "EditorIcons"); extension_guess["gd"] = tree->get_theme_icon("GDScript", "EditorIcons"); extension_guess["vs"] = tree->get_theme_icon("VisualScript", "EditorIcons"); } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9c77f9d25c..22d04add18 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -119,7 +119,6 @@ #include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" #include "editor/plugins/audio_stream_editor_plugin.h" -#include "editor/plugins/baked_lightmap_editor_plugin.h" #include "editor/plugins/camera_3d_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/collision_polygon_2d_editor_plugin.h" @@ -132,13 +131,13 @@ #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/editor_preview_plugins.h" #include "editor/plugins/font_editor_plugin.h" -#include "editor/plugins/gi_probe_editor_plugin.h" #include "editor/plugins/gpu_particles_2d_editor_plugin.h" #include "editor/plugins/gpu_particles_3d_editor_plugin.h" #include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h" #include "editor/plugins/gradient_editor_plugin.h" #include "editor/plugins/item_list_editor_plugin.h" #include "editor/plugins/light_occluder_2d_editor_plugin.h" +#include "editor/plugins/lightmap_gi_editor_plugin.h" #include "editor/plugins/line_2d_editor_plugin.h" #include "editor/plugins/material_editor_plugin.h" #include "editor/plugins/mesh_editor_plugin.h" @@ -175,6 +174,7 @@ #include "editor/plugins/tiles/tiles_editor_plugin.h" #include "editor/plugins/version_control_editor_plugin.h" #include "editor/plugins/visual_shader_editor_plugin.h" +#include "editor/plugins/voxel_gi_editor_plugin.h" #include "editor/progress_dialog.h" #include "editor/project_export.h" #include "editor/project_settings_editor.h" @@ -484,8 +484,8 @@ void EditorNode::_update_from_settings() { RS::get_singleton()->environment_set_sdfgi_frames_to_converge(frames_to_converge); RS::EnvironmentSDFGIRayCount ray_count = RS::EnvironmentSDFGIRayCount(int(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count"))); RS::get_singleton()->environment_set_sdfgi_ray_count(ray_count); - RS::GIProbeQuality gi_probe_quality = RS::GIProbeQuality(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality"))); - RS::get_singleton()->gi_probe_set_quality(gi_probe_quality); + RS::VoxelGIQuality voxel_gi_quality = RS::VoxelGIQuality(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality"))); + RS::get_singleton()->voxel_gi_set_quality(voxel_gi_quality); RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth")); RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"))); RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size")); @@ -1587,6 +1587,8 @@ void EditorNode::_save_scene(String p_file, int idx) { return; } + scene->propagate_notification(NOTIFICATION_EDITOR_PRE_SAVE); + editor_data.apply_changes_in_editors(); List<Ref<AnimatedValuesBackup>> anim_backups; _reset_animation_players(scene, &anim_backups); @@ -1658,6 +1660,8 @@ void EditorNode::_save_scene(String p_file, int idx) { } else { _dialog_display_save_error(p_file, err); } + + scene->propagate_notification(NOTIFICATION_EDITOR_POST_SAVE); } void EditorNode::save_all_scenes() { @@ -2157,9 +2161,14 @@ void EditorNode::_edit_current() { if (!inspector_only) { EditorPlugin *main_plugin = editor_data.get_editor(current_obj); - for (int i = 0; i < editor_table.size(); i++) { - if (editor_table[i] == main_plugin && !main_editor_buttons[i]->is_visible()) { - main_plugin = nullptr; //if button is not visible, then no plugin active + int plugin_index = 0; + for (; plugin_index < editor_table.size(); plugin_index++) { + if (editor_table[plugin_index] == main_plugin) { + if (!main_editor_buttons[plugin_index]->is_visible()) { + main_plugin = nullptr; //if button is not visible, then no plugin active + } + + break; } } @@ -2173,26 +2182,8 @@ void EditorNode::_edit_current() { else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) { // update screen main_plugin - - if (!changing_scene) { - if (editor_plugin_screen) { - editor_plugin_screen->make_visible(false); - } - editor_plugin_screen = main_plugin; - editor_plugin_screen->edit(current_obj); - - editor_plugin_screen->make_visible(true); - - int plugin_count = editor_data.get_editor_plugin_count(); - for (int i = 0; i < plugin_count; i++) { - editor_data.get_editor_plugin(i)->notify_main_screen_changed(editor_plugin_screen->get_name()); - } - - for (int i = 0; i < editor_table.size(); i++) { - main_editor_buttons[i]->set_pressed(editor_table[i] == main_plugin); - } - } - + _editor_select(plugin_index); + main_plugin->edit(current_obj); } else { editor_plugin_screen->edit(current_obj); } @@ -2754,7 +2745,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_data_dir()); } break; case SETTINGS_EDITOR_CONFIG_FOLDER: { - OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_settings_dir()); + OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_config_dir()); } break; case SETTINGS_MANAGE_EXPORT_TEMPLATES: { export_template_manager->popup_manager(); @@ -6628,7 +6619,7 @@ EditorNode::EditorNode() { version_btn->set_text(VERSION_FULL_CONFIG); String hash = String(VERSION_HASH); if (hash.length() != 0) { - hash = "." + hash.left(9); + hash = " " + vformat("[%s]", hash.left(9)); } // Set the text to copy in metadata as it slightly differs from the button's text. version_btn->set_meta(META_TEXT_TO_COPY, "v" VERSION_FULL_BUILD + hash); @@ -6818,8 +6809,8 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(TilesEditorPlugin(this))); add_editor_plugin(memnew(SpriteFramesEditorPlugin(this))); add_editor_plugin(memnew(TextureRegionEditorPlugin(this))); - add_editor_plugin(memnew(GIProbeEditorPlugin(this))); - add_editor_plugin(memnew(BakedLightmapEditorPlugin(this))); + add_editor_plugin(memnew(VoxelGIEditorPlugin(this))); + add_editor_plugin(memnew(LightmapGIEditorPlugin(this))); add_editor_plugin(memnew(OccluderInstance3DEditorPlugin(this))); add_editor_plugin(memnew(Path2DEditorPlugin(this))); add_editor_plugin(memnew(Path3DEditorPlugin(this))); diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp index d1c52b4310..63281ae1aa 100644 --- a/editor/editor_path.cpp +++ b/editor/editor_path.cpp @@ -59,15 +59,40 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) { Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj); - int index = get_popup()->get_item_count(); - get_popup()->add_icon_item(icon, E->get().name.capitalize(), objects.size()); - get_popup()->set_item_h_offset(index, p_depth * 10 * EDSCALE); + String proper_name = ""; + Vector<String> name_parts = E->get().name.split("/"); + + for (int i = 0; i < name_parts.size(); i++) { + if (i > 0) { + proper_name += " > "; + } + proper_name += name_parts[i].capitalize(); + } + + int index = sub_objects_menu->get_item_count(); + sub_objects_menu->add_icon_item(icon, proper_name, objects.size()); + sub_objects_menu->set_item_h_offset(index, p_depth * 10 * EDSCALE); objects.push_back(obj->get_instance_id()); _add_children_to_popup(obj, p_depth + 1); } } +void EditorPath::_show_popup() { + sub_objects_menu->clear(); + + Size2 size = get_size(); + Point2 gp = get_screen_position(); + gp.y += size.y; + + sub_objects_menu->set_position(gp); + sub_objects_menu->set_size(Size2(size.width, 1)); + sub_objects_menu->set_parent_rect(Rect2(Point2(gp - sub_objects_menu->get_position()), size)); + + sub_objects_menu->take_mouse_focus(); + sub_objects_menu->popup(); +} + void EditorPath::_about_to_show() { Object *obj = ObjectDB::get_instance(history->get_path_object(history->get_path_size() - 1)); if (!obj) { @@ -75,13 +100,11 @@ void EditorPath::_about_to_show() { } objects.clear(); - get_popup()->clear(); - get_popup()->set_size(Size2(get_size().width, 1)); _add_children_to_popup(obj); - if (get_popup()->get_item_count() == 0) { - get_popup()->add_item(TTR("No sub-resources found.")); - get_popup()->set_item_disabled(0, true); + if (sub_objects_menu->get_item_count() == 0) { + sub_objects_menu->add_item(TTR("No sub-resources found.")); + sub_objects_menu->set_item_disabled(0, true); } } @@ -94,7 +117,7 @@ void EditorPath::update_path() { Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj); if (icon.is_valid()) { - set_icon(icon); + current_object_icon->set_texture(icon); } if (i == history->get_path_size() - 1) { @@ -120,12 +143,26 @@ void EditorPath::update_path() { name = obj->get_class(); } - set_text(" " + name); // An extra space so the text is not too close of the icon. + current_object_label->set_text(" " + name); // An extra space so the text is not too close of the icon. set_tooltip(obj->get_class()); } } } +void EditorPath::clear_path() { + set_disabled(true); + set_tooltip(""); + + current_object_label->set_text(""); + current_object_icon->set_texture(nullptr); + sub_objects_icon->set_visible(false); +} + +void EditorPath::enable_path() { + set_disabled(false); + sub_objects_icon->set_visible(true); +} + void EditorPath::_id_pressed(int p_idx) { ERR_FAIL_INDEX(p_idx, objects.size()); @@ -139,8 +176,16 @@ void EditorPath::_id_pressed(int p_idx) { void EditorPath::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { update_path(); + + sub_objects_icon->set_texture(get_theme_icon("select_arrow", "Tree")); + current_object_label->add_theme_font_override("font", get_theme_font("main", "EditorFonts")); + } break; + + case NOTIFICATION_READY: { + connect("pressed", callable_mp(this, &EditorPath::_show_popup)); } break; } } @@ -150,8 +195,35 @@ void EditorPath::_bind_methods() { EditorPath::EditorPath(EditorHistory *p_history) { history = p_history; - set_clip_text(true); - set_text_align(ALIGN_LEFT); - get_popup()->connect("about_to_popup", callable_mp(this, &EditorPath::_about_to_show)); - get_popup()->connect("id_pressed", callable_mp(this, &EditorPath::_id_pressed)); + + MarginContainer *main_mc = memnew(MarginContainer); + main_mc->set_anchors_and_offsets_preset(PRESET_WIDE); + main_mc->add_theme_constant_override("margin_left", 4 * EDSCALE); + main_mc->add_theme_constant_override("margin_right", 6 * EDSCALE); + add_child(main_mc); + + HBoxContainer *main_hb = memnew(HBoxContainer); + main_mc->add_child(main_hb); + + current_object_icon = memnew(TextureRect); + current_object_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + main_hb->add_child(current_object_icon); + + current_object_label = memnew(Label); + current_object_label->set_clip_text(true); + current_object_label->set_align(Label::ALIGN_LEFT); + current_object_label->set_h_size_flags(SIZE_EXPAND_FILL); + main_hb->add_child(current_object_label); + + sub_objects_icon = memnew(TextureRect); + sub_objects_icon->set_visible(false); + sub_objects_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + main_hb->add_child(sub_objects_icon); + + sub_objects_menu = memnew(PopupMenu); + add_child(sub_objects_menu); + sub_objects_menu->connect("about_to_popup", callable_mp(this, &EditorPath::_about_to_show)); + sub_objects_menu->connect("id_pressed", callable_mp(this, &EditorPath::_id_pressed)); + + set_tooltip(TTR("Open a list of sub-resources.")); } diff --git a/editor/editor_path.h b/editor/editor_path.h index d1090947f9..cabfa931d6 100644 --- a/editor/editor_path.h +++ b/editor/editor_path.h @@ -32,16 +32,24 @@ #define EDITOR_PATH_H #include "editor_data.h" -#include "scene/gui/menu_button.h" +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/popup_menu.h" -class EditorPath : public MenuButton { - GDCLASS(EditorPath, MenuButton); +class EditorPath : public Button { + GDCLASS(EditorPath, Button); EditorHistory *history; + TextureRect *current_object_icon; + Label *current_object_label; + TextureRect *sub_objects_icon; + PopupMenu *sub_objects_menu; + Vector<ObjectID> objects; EditorPath(); + void _show_popup(); void _id_pressed(int p_idx); void _about_to_show(); void _add_children_to_popup(Object *p_obj, int p_depth = 0); @@ -52,6 +60,8 @@ protected: public: void update_path(); + void clear_path(); + void enable_path(); EditorPath(EditorHistory *p_history); }; diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index 96469d3143..474da4fb96 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -38,9 +38,6 @@ bool EditorPaths::are_paths_valid() const { return paths_valid; } -String EditorPaths::get_settings_dir() const { - return settings_dir; -} String EditorPaths::get_data_dir() const { return data_dir; } @@ -67,7 +64,6 @@ void EditorPaths::free() { } void EditorPaths::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_settings_dir"), &EditorPaths::get_settings_dir); ClassDB::bind_method(D_METHOD("get_data_dir"), &EditorPaths::get_data_dir); ClassDB::bind_method(D_METHOD("get_config_dir"), &EditorPaths::get_config_dir); ClassDB::bind_method(D_METHOD("get_cache_dir"), &EditorPaths::get_cache_dir); diff --git a/editor/editor_paths.h b/editor/editor_paths.h index 096174943d..c1be33f5c2 100644 --- a/editor/editor_paths.h +++ b/editor/editor_paths.h @@ -37,7 +37,6 @@ class EditorPaths : public Object { GDCLASS(EditorPaths, Object) bool paths_valid = false; - String settings_dir; String data_dir; //editor data dir String config_dir; //editor config dir String cache_dir; //editor cache dir @@ -52,7 +51,6 @@ protected: public: bool are_paths_valid() const; - String get_settings_dir() const; String get_data_dir() const; String get_config_dir() const; String get_cache_dir() const; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index c5097a17a5..a12bf036bc 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -60,7 +60,7 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_ return ret; } -Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) { +Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size) { int size = p_preview_size; RID scenario = RS::get_singleton()->scenario_create(); @@ -94,7 +94,7 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh continue; } - Transform mesh_xform; + Transform3D mesh_xform; if (p_transforms != nullptr) { mesh_xform = (*p_transforms)[i]; } @@ -105,7 +105,7 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh AABB aabb = mesh->get_aabb(); Vector3 ofs = aabb.position + aabb.size * 0.5; aabb.position -= ofs; - Transform xform; + Transform3D xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI / 6); xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI / 6) * xform.basis; AABB rot_aabb = xform.xform(aabb); @@ -119,11 +119,11 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh xform.invert(); xform = mesh_xform * xform; - RS::get_singleton()->camera_set_transform(camera, xform * Transform(Basis(), Vector3(0, 0, 3))); + RS::get_singleton()->camera_set_transform(camera, xform * Transform3D(Basis(), Vector3(0, 0, 3))); RS::get_singleton()->camera_set_orthogonal(camera, m * 2, 0.01, 1000.0); - RS::get_singleton()->instance_set_transform(light_instance, xform * Transform().looking_at(Vector3(-2, -1, -1), Vector3(0, 1, 0))); - RS::get_singleton()->instance_set_transform(light_instance2, xform * Transform().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0))); + RS::get_singleton()->instance_set_transform(light_instance, xform * Transform3D().looking_at(Vector3(-2, -1, -1), Vector3(0, 1, 0))); + RS::get_singleton()->instance_set_transform(light_instance2, xform * Transform3D().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0))); ep.step(TTR("Thumbnail..."), i); Main::iteration(); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 3f72e468b2..2e1dd0a0c1 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -113,7 +113,7 @@ public: Error save_scene(); void save_scene_as(const String &p_scene, bool p_with_preview = true); - Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size); + Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size); void set_main_screen_editor(const String &p_name); void set_distraction_free_mode(bool p_enter); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 7beff4147d..ece7094767 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1761,14 +1761,14 @@ EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) { setting = false; } -///////////////////// QUAT ///////////////////////// +///////////////////// QUATERNION ///////////////////////// -void EditorPropertyQuat::_value_changed(double val, const String &p_name) { +void EditorPropertyQuaternion::_value_changed(double val, const String &p_name) { if (setting) { return; } - Quat p; + Quaternion p; p.x = spin[0]->get_value(); p.y = spin[1]->get_value(); p.z = spin[2]->get_value(); @@ -1776,8 +1776,8 @@ void EditorPropertyQuat::_value_changed(double val, const String &p_name) { emit_changed(get_edited_property(), p, p_name); } -void EditorPropertyQuat::update_property() { - Quat val = get_edited_object()->get(get_edited_property()); +void EditorPropertyQuaternion::update_property() { + Quaternion val = get_edited_object()->get(get_edited_property()); setting = true; spin[0]->set_value(val.x); spin[1]->set_value(val.y); @@ -1786,7 +1786,7 @@ void EditorPropertyQuat::update_property() { setting = false; } -void EditorPropertyQuat::_notification(int p_what) { +void EditorPropertyQuaternion::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { Color base = get_theme_color("accent_color", "Editor"); for (int i = 0; i < 3; i++) { @@ -1797,10 +1797,10 @@ void EditorPropertyQuat::_notification(int p_what) { } } -void EditorPropertyQuat::_bind_methods() { +void EditorPropertyQuaternion::_bind_methods() { } -void EditorPropertyQuat::setup(double p_min, double p_max, double p_step, bool p_no_slider) { +void EditorPropertyQuaternion::setup(double p_min, double p_max, double p_step, bool p_no_slider) { for (int i = 0; i < 4; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1811,7 +1811,7 @@ void EditorPropertyQuat::setup(double p_min, double p_max, double p_step, bool p } } -EditorPropertyQuat::EditorPropertyQuat() { +EditorPropertyQuaternion::EditorPropertyQuaternion() { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; @@ -1832,7 +1832,7 @@ EditorPropertyQuat::EditorPropertyQuat() { spin[i]->set_label(desc[i]); bc->add_child(spin[i]); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyQuat::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyQuaternion::_value_changed), varray(desc[i])); if (horizontal) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } @@ -2078,12 +2078,12 @@ EditorPropertyBasis::EditorPropertyBasis() { ///////////////////// TRANSFORM ///////////////////////// -void EditorPropertyTransform::_value_changed(double val, const String &p_name) { +void EditorPropertyTransform3D::_value_changed(double val, const String &p_name) { if (setting) { return; } - Transform p; + Transform3D p; p.basis[0][0] = spin[0]->get_value(); p.basis[1][0] = spin[1]->get_value(); p.basis[2][0] = spin[2]->get_value(); @@ -2100,11 +2100,11 @@ void EditorPropertyTransform::_value_changed(double val, const String &p_name) { emit_changed(get_edited_property(), p, p_name); } -void EditorPropertyTransform::update_property() { +void EditorPropertyTransform3D::update_property() { update_using_transform(get_edited_object()->get(get_edited_property())); } -void EditorPropertyTransform::update_using_transform(Transform p_transform) { +void EditorPropertyTransform3D::update_using_transform(Transform3D p_transform) { setting = true; spin[0]->set_value(p_transform.basis[0][0]); spin[1]->set_value(p_transform.basis[1][0]); @@ -2121,7 +2121,7 @@ void EditorPropertyTransform::update_using_transform(Transform p_transform) { setting = false; } -void EditorPropertyTransform::_notification(int p_what) { +void EditorPropertyTransform3D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { Color base = get_theme_color("accent_color", "Editor"); for (int i = 0; i < 12; i++) { @@ -2132,10 +2132,10 @@ void EditorPropertyTransform::_notification(int p_what) { } } -void EditorPropertyTransform::_bind_methods() { +void EditorPropertyTransform3D::_bind_methods() { } -void EditorPropertyTransform::setup(double p_min, double p_max, double p_step, bool p_no_slider) { +void EditorPropertyTransform3D::setup(double p_min, double p_max, double p_step, bool p_no_slider) { for (int i = 0; i < 12; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -2146,7 +2146,7 @@ void EditorPropertyTransform::setup(double p_min, double p_max, double p_step, b } } -EditorPropertyTransform::EditorPropertyTransform() { +EditorPropertyTransform3D::EditorPropertyTransform3D() { GridContainer *g = memnew(GridContainer); g->set_columns(3); add_child(g); @@ -2159,7 +2159,7 @@ EditorPropertyTransform::EditorPropertyTransform() { g->add_child(spin[i]); spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); add_focusable(spin[i]); - spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform::_value_changed), varray(desc[i])); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyTransform3D::_value_changed), varray(desc[i])); } set_bottom_editor(g); setting = false; @@ -3056,8 +3056,8 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ editor->setup(min, max, step, hide_slider); add_property_editor(p_path, editor); } break; - case Variant::QUAT: { - EditorPropertyQuat *editor = memnew(EditorPropertyQuat); + case Variant::QUATERNION: { + EditorPropertyQuaternion *editor = memnew(EditorPropertyQuaternion); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3107,8 +3107,8 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ editor->setup(min, max, step, hide_slider); add_property_editor(p_path, editor); } break; - case Variant::TRANSFORM: { - EditorPropertyTransform *editor = memnew(EditorPropertyTransform); + case Variant::TRANSFORM3D: { + EditorPropertyTransform3D *editor = memnew(EditorPropertyTransform3D); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 07f496f54d..121848d936 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -465,8 +465,8 @@ public: EditorPropertyPlane(bool p_force_wide = false); }; -class EditorPropertyQuat : public EditorProperty { - GDCLASS(EditorPropertyQuat, EditorProperty); +class EditorPropertyQuaternion : public EditorProperty { + GDCLASS(EditorPropertyQuaternion, EditorProperty); EditorSpinSlider *spin[4]; bool setting; void _value_changed(double p_val, const String &p_name); @@ -478,7 +478,7 @@ protected: public: virtual void update_property() override; void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyQuat(); + EditorPropertyQuaternion(); }; class EditorPropertyAABB : public EditorProperty { @@ -529,8 +529,8 @@ public: EditorPropertyBasis(); }; -class EditorPropertyTransform : public EditorProperty { - GDCLASS(EditorPropertyTransform, EditorProperty); +class EditorPropertyTransform3D : public EditorProperty { + GDCLASS(EditorPropertyTransform3D, EditorProperty); EditorSpinSlider *spin[12]; bool setting; void _value_changed(double p_val, const String &p_name); @@ -541,9 +541,9 @@ protected: public: virtual void update_property() override; - virtual void update_using_transform(Transform p_transform); + virtual void update_using_transform(Transform3D p_transform); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyTransform(); + EditorPropertyTransform3D(); }; class EditorPropertyColor : public EditorProperty { diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 3bc29856f1..bfa85f4aab 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -850,8 +850,8 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; - case Variant::QUAT: { - EditorPropertyQuat *editor = memnew(EditorPropertyQuat); + case Variant::QUATERNION: { + EditorPropertyQuaternion *editor = memnew(EditorPropertyQuaternion); editor->setup(-100000, 100000, 0.001, true); prop = editor; @@ -868,8 +868,8 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; - case Variant::TRANSFORM: { - EditorPropertyTransform *editor = memnew(EditorPropertyTransform); + case Variant::TRANSFORM3D: { + EditorPropertyTransform3D *editor = memnew(EditorPropertyTransform3D); editor->setup(-100000, 100000, 0.001, true); prop = editor; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index e4072f7d4b..71dc1b531a 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -689,11 +689,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8)); _initial_set("editors/2d/smart_snapping_line_color", Color(0.9, 0.1, 0.1)); _initial_set("editors/2d/bone_width", 5); - _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); - _initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.9)); - _initial_set("editors/2d/bone_selected_color", Color(0.9, 0.45, 0.45, 0.9)); - _initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9)); - _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35)); + _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.7)); + _initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.7)); + _initial_set("editors/2d/bone_selected_color", Color(0.9, 0.45, 0.45, 0.7)); + _initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.7)); + _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35, 0.5)); _initial_set("editors/2d/bone_outline_size", 2); _initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4)); _initial_set("editors/2d/constrain_editor_view", true); @@ -1264,11 +1264,11 @@ String EditorSettings::get_project_settings_dir() const { } String EditorSettings::get_text_editor_themes_dir() const { - return EditorPaths::get_singleton()->get_settings_dir().plus_file("text_editor_themes"); + return EditorPaths::get_singleton()->get_config_dir().plus_file("text_editor_themes"); } String EditorSettings::get_script_templates_dir() const { - return EditorPaths::get_singleton()->get_settings_dir().plus_file("script_templates"); + return EditorPaths::get_singleton()->get_config_dir().plus_file("script_templates"); } String EditorSettings::get_project_script_templates_dir() const { @@ -1278,7 +1278,7 @@ String EditorSettings::get_project_script_templates_dir() const { // Cache directory String EditorSettings::get_feature_profiles_dir() const { - return EditorPaths::get_singleton()->get_settings_dir().plus_file("feature_profiles"); + return EditorPaths::get_singleton()->get_config_dir().plus_file("feature_profiles"); } // Metadata @@ -1505,7 +1505,7 @@ Vector<String> EditorSettings::get_script_templates(const String &p_extension, c } String EditorSettings::get_editor_layouts_config() const { - return EditorPaths::get_singleton()->get_settings_dir().plus_file("editor_layouts.cfg"); + return EditorPaths::get_singleton()->get_config_dir().plus_file("editor_layouts.cfg"); } // Shortcuts diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 5efb7cdbf2..64f7500e8c 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -217,6 +217,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = exceptions.insert("EditorControlAnchor"); exceptions.insert("DefaultProjectIcon"); exceptions.insert("GuiChecked"); + exceptions.insert("GuiRadioChecked"); exceptions.insert("GuiCloseCustomizable"); exceptions.insert("GuiGraphNodePort"); exceptions.insert("GuiResizer"); diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 6e0ae403a2..39d7c7acd4 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -41,141 +41,336 @@ #include "progress_dialog.h" #include "scene/gui/link_button.h" -void ExportTemplateManager::_update_template_list() { - while (current_hb->get_child_count()) { - memdelete(current_hb->get_child(0)); - } - - while (installed_vb->get_child_count()) { - memdelete(installed_vb->get_child(0)); - } +void ExportTemplateManager::_update_template_status() { + // Fetch installed templates from the file system. + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); - DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - Error err = d->change_dir(EditorSettings::get_singleton()->get_templates_dir()); + Error err = da->change_dir(templates_dir); + ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); Set<String> templates; - d->list_dir_begin(); + da->list_dir_begin(); if (err == OK) { - String c = d->get_next(); + String c = da->get_next(); while (c != String()) { - if (d->current_is_dir() && !c.begins_with(".")) { + if (da->current_is_dir() && !c.begins_with(".")) { templates.insert(c); } - c = d->get_next(); + c = da->get_next(); } } - d->list_dir_end(); - - memdelete(d); + da->list_dir_end(); + memdelete(da); + // Update the state of the current version. String current_version = VERSION_FULL_CONFIG; - // Downloadable export templates are only available for stable and official alpha/beta/RC builds - // (which always have a number following their status, e.g. "alpha1"). - // Therefore, don't display download-related features when using a development version - // (whose builds aren't numbered). - const bool downloads_available = - String(VERSION_STATUS) != String("dev") && - String(VERSION_STATUS) != String("alpha") && - String(VERSION_STATUS) != String("beta") && - String(VERSION_STATUS) != String("rc"); - - Label *current = memnew(Label); - current->set_h_size_flags(Control::SIZE_EXPAND_FILL); - current_hb->add_child(current); + current_value->set_text(current_version); if (templates.has(current_version)) { - current->add_theme_color_override("font_color", current->get_theme_color("success_color", "Editor")); - - // Only display a redownload button if it can be downloaded in the first place - if (downloads_available) { - Button *redownload = memnew(Button); - redownload->set_text(TTR("Redownload")); - current_hb->add_child(redownload); - redownload->connect("pressed", callable_mp(this, &ExportTemplateManager::_download_template), varray(current_version)); - } + current_missing_label->hide(); + current_installed_label->show(); + + current_installed_hb->show(); + current_version_exists = true; + } else { + current_installed_label->hide(); + current_missing_label->show(); - Button *uninstall = memnew(Button); - uninstall->set_text(TTR("Uninstall")); - current_hb->add_child(uninstall); - current->set_text(current_version + " " + TTR("(Installed)")); - uninstall->connect("pressed", callable_mp(this, &ExportTemplateManager::_uninstall_template), varray(current_version)); + current_installed_hb->hide(); + current_version_exists = false; + } + if (is_downloading_templates) { + install_options_vb->hide(); + download_progress_hb->show(); } else { - current->add_theme_color_override("font_color", current->get_theme_color("error_color", "Editor")); - Button *redownload = memnew(Button); - redownload->set_text(TTR("Download")); + download_progress_hb->hide(); + install_options_vb->show(); - if (!downloads_available) { - redownload->set_disabled(true); - redownload->set_tooltip(TTR("Official export templates aren't available for development builds.")); + if (templates.has(current_version)) { + current_installed_path->set_text(templates_dir.plus_file(current_version)); } - - redownload->connect("pressed", callable_mp(this, &ExportTemplateManager::_download_template), varray(current_version)); - current_hb->add_child(redownload); - current->set_text(current_version + " " + TTR("(Missing)")); } + // Update the list of other installed versions. + installed_table->clear(); + TreeItem *installed_root = installed_table->create_item(); + for (Set<String>::Element *E = templates.back(); E; E = E->prev()) { - String text = E->get(); - if (text == current_version) { + String version_string = E->get(); + if (version_string == current_version) { continue; } - HBoxContainer *hbc = memnew(HBoxContainer); - Label *version = memnew(Label); - version->set_modulate(current->get_theme_color("disabled_font_color", "Editor")); - version->set_text(text); - version->set_h_size_flags(Control::SIZE_EXPAND_FILL); - hbc->add_child(version); + TreeItem *ti = installed_table->create_item(installed_root); + ti->set_text(0, version_string); + + ti->add_button(0, get_theme_icon("Folder", "EditorIcons"), OPEN_TEMPLATE_FOLDER, false, TTR("Open the folder containing these templates.")); + ti->add_button(0, get_theme_icon("Remove", "EditorIcons"), UNINSTALL_TEMPLATE, false, TTR("Uninstall these templates.")); + } +} + +void ExportTemplateManager::_download_current() { + if (is_downloading_templates) { + return; + } + is_downloading_templates = true; - Button *uninstall = memnew(Button); + install_options_vb->hide(); + download_progress_hb->show(); - uninstall->set_text(TTR("Uninstall")); - hbc->add_child(uninstall); - uninstall->connect("pressed", callable_mp(this, &ExportTemplateManager::_uninstall_template), varray(E->get())); + if (mirrors_available) { + String mirror_url = _get_selected_mirror(); + if (mirror_url.is_empty()) { + _set_current_progress_status(TTR("There are no mirrors available."), true); + return; + } - installed_vb->add_child(hbc); + _download_template(mirror_url, true); + } else if (!mirrors_available && !is_refreshing_mirrors) { + _set_current_progress_status(TTR("Retrieving the mirror list...")); + _refresh_mirrors(); } } -void ExportTemplateManager::_download_template(const String &p_version) { - while (template_list->get_child_count()) { - memdelete(template_list->get_child(0)); - } - template_downloader->popup_centered(); - template_list_state->set_text(TTR("Retrieving mirrors, please wait...")); - template_download_progress->set_max(100); - template_download_progress->set_value(0); - request_mirror->request("https://godotengine.org/mirrorlist/" + p_version + ".json"); - template_list_state->show(); - template_download_progress->show(); +void ExportTemplateManager::_download_template(const String &p_url, bool p_skip_check) { + if (!p_skip_check && is_downloading_templates) { + return; + } + is_downloading_templates = true; + + install_options_vb->hide(); + download_progress_hb->show(); + _set_current_progress_status(TTR("Starting the download...")); + + download_templates->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz")); + download_templates->set_use_threads(true); + + Error err = download_templates->request(p_url); + if (err != OK) { + _set_current_progress_status(TTR("Error requesting URL:") + " " + p_url, true); + return; + } + + set_process(true); + _set_current_progress_status(TTR("Connecting to the mirror...")); } -void ExportTemplateManager::_uninstall_template(const String &p_version) { - remove_confirm->set_text(vformat(TTR("Remove template version '%s'?"), p_version)); - remove_confirm->popup_centered(); - to_remove = p_version; +void ExportTemplateManager::_download_template_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { + switch (p_status) { + case HTTPRequest::RESULT_CANT_RESOLVE: { + _set_current_progress_status(TTR("Can't resolve the requested address."), true); + } break; + case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: + case HTTPRequest::RESULT_CONNECTION_ERROR: + case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: + case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: + case HTTPRequest::RESULT_CANT_CONNECT: { + _set_current_progress_status(TTR("Can't connect to the mirror."), true); + } break; + case HTTPRequest::RESULT_NO_RESPONSE: { + _set_current_progress_status(TTR("No response from the mirror."), true); + } break; + case HTTPRequest::RESULT_REQUEST_FAILED: { + _set_current_progress_status(TTR("Request failed."), true); + } break; + case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: { + _set_current_progress_status(TTR("Request ended up in a redirect loop."), true); + } break; + default: { + if (p_code != 200) { + _set_current_progress_status(TTR("Request failed:") + " " + itos(p_code), true); + } else { + _set_current_progress_status(TTR("Download complete; extracting templates...")); + String path = download_templates->get_download_file(); + + is_downloading_templates = false; + bool ret = _install_file_selected(path, true); + if (ret) { + // Clean up downloaded file. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Error err = da->remove(path); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Cannot remove temporary file:") + "\n" + path + "\n"); + } + } else { + EditorNode::get_singleton()->add_io_error(vformat(TTR("Templates installation failed.\nThe problematic templates archives can be found at '%s'."), path)); + } + } + } break; + } + + set_process(false); } -void ExportTemplateManager::_uninstall_template_confirm() { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); - Error err = da->change_dir(templates_dir); - ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); - err = da->change_dir(to_remove); - ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir.plus_file(to_remove) + "'."); +void ExportTemplateManager::_cancel_template_download() { + if (!is_downloading_templates) { + return; + } - err = da->erase_contents_recursive(); - ERR_FAIL_COND_MSG(err != OK, "Could not remove all templates in '" + templates_dir.plus_file(to_remove) + "'."); + download_templates->cancel_request(); + download_progress_hb->hide(); + install_options_vb->show(); + is_downloading_templates = false; +} - da->change_dir(".."); - err = da->remove(to_remove); - ERR_FAIL_COND_MSG(err != OK, "Could not remove templates directory at '" + templates_dir.plus_file(to_remove) + "'."); +void ExportTemplateManager::_refresh_mirrors() { + if (is_refreshing_mirrors) { + return; + } + is_refreshing_mirrors = true; + + String current_version = VERSION_FULL_CONFIG; + const String mirrors_metadata_url = "https://godotengine.org/mirrorlist/" + current_version + ".json"; + request_mirrors->request(mirrors_metadata_url); +} + +void ExportTemplateManager::_refresh_mirrors_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { + if (p_status != HTTPRequest::RESULT_SUCCESS || p_code != 200) { + EditorNode::get_singleton()->show_warning(TTR("Error getting the list of mirrors.")); + is_refreshing_mirrors = false; + if (is_downloading_templates) { + _cancel_template_download(); + } + return; + } + + String response_json; + { + const uint8_t *r = p_data.ptr(); + response_json.parse_utf8((const char *)r, p_data.size()); + } + + Variant response; + String errs; + int errline; + Error err = JSON::parse(response_json, response, errs, errline); + if (err != OK) { + EditorNode::get_singleton()->show_warning(TTR("Error parsing JSON with the list of mirrors. Please report this issue!")); + is_refreshing_mirrors = false; + if (is_downloading_templates) { + _cancel_template_download(); + } + return; + } + + mirrors_list->clear(); + mirrors_list->add_item(TTR("Best available mirror"), 0); + + mirrors_available = false; + + Dictionary data = response; + if (data.has("mirrors")) { + Array mirrors = data["mirrors"]; + + for (int i = 0; i < mirrors.size(); i++) { + Dictionary m = mirrors[i]; + ERR_CONTINUE(!m.has("url") || !m.has("name")); + + mirrors_list->add_item(m["name"]); + mirrors_list->set_item_metadata(i + 1, m["url"]); + + mirrors_available = true; + } + } + if (!mirrors_available) { + EditorNode::get_singleton()->show_warning(TTR("No download links found for this version. Direct download is only available for official releases.")); + if (is_downloading_templates) { + _cancel_template_download(); + } + } + + is_refreshing_mirrors = false; + + if (is_downloading_templates) { + String mirror_url = _get_selected_mirror(); + if (mirror_url.is_empty()) { + _set_current_progress_status(TTR("There are no mirrors available."), true); + return; + } + + _download_template(mirror_url, true); + } +} + +bool ExportTemplateManager::_humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes) { + *r_status = ""; + *r_downloaded_bytes = -1; + *r_total_bytes = -1; + bool success = true; + + switch (p_request->get_http_client_status()) { + case HTTPClient::STATUS_DISCONNECTED: + *r_status = TTR("Disconnected"); + success = false; + break; + case HTTPClient::STATUS_RESOLVING: + *r_status = TTR("Resolving"); + break; + case HTTPClient::STATUS_CANT_RESOLVE: + *r_status = TTR("Can't Resolve"); + success = false; + break; + case HTTPClient::STATUS_CONNECTING: + *r_status = TTR("Connecting..."); + break; + case HTTPClient::STATUS_CANT_CONNECT: + *r_status = TTR("Can't Connect"); + success = false; + break; + case HTTPClient::STATUS_CONNECTED: + *r_status = TTR("Connected"); + break; + case HTTPClient::STATUS_REQUESTING: + *r_status = TTR("Requesting..."); + break; + case HTTPClient::STATUS_BODY: + *r_status = TTR("Downloading"); + *r_downloaded_bytes = p_request->get_downloaded_bytes(); + *r_total_bytes = p_request->get_body_size(); + + if (p_request->get_body_size() > 0) { + *r_status += " " + String::humanize_size(p_request->get_downloaded_bytes()) + "/" + String::humanize_size(p_request->get_body_size()); + } else { + *r_status += " " + String::humanize_size(p_request->get_downloaded_bytes()); + } + break; + case HTTPClient::STATUS_CONNECTION_ERROR: + *r_status = TTR("Connection Error"); + success = false; + break; + case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: + *r_status = TTR("SSL Handshake Error"); + success = false; + break; + } + + return success; +} + +void ExportTemplateManager::_set_current_progress_status(const String &p_status, bool p_error) { + download_progress_bar->hide(); + download_progress_label->set_text(p_status); + + if (p_error) { + download_progress_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); + } else { + download_progress_label->add_theme_color_override("font_color", get_theme_color("font_color", "Label")); + } +} + +void ExportTemplateManager::_set_current_progress_value(float p_value, const String &p_status) { + download_progress_bar->show(); + download_progress_bar->set_value(p_value); + download_progress_label->set_text(p_status); +} - _update_template_list(); +void ExportTemplateManager::_install_file() { + install_file_dialog->popup_file_dialog(); } -bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_progress) { +bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_skip_progress) { // unzClose() will take care of closing the file stored in the unzFile, // so we don't need to `memdelete(fa)` in this method. FileAccess *fa = nullptr; @@ -183,12 +378,13 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io); if (!pkg) { - EditorNode::get_singleton()->show_warning(TTR("Can't open export templates zip.")); + EditorNode::get_singleton()->show_warning(TTR("Can't open the export templates file.")); return false; } int ret = unzGoToFirstFile(pkg); - int fc = 0; //count them and find version + // Count them and find version. + int fc = 0; String version; String contents_dir; @@ -198,12 +394,11 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0); String file = fname; - if (file.ends_with("version.txt")) { Vector<uint8_t> data; data.resize(info.uncompressed_size); - //read + // Read. unzOpenCurrentFile(pkg); ret = unzReadCurrentFile(pkg, data.ptrw(), data.size()); unzCloseCurrentFile(pkg); @@ -215,7 +410,7 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ // Version number should be of the form major.minor[.patch].status[.module_config] // so it can in theory have 3 or more slices. if (data_str.get_slice_count(".") < 3) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid version.txt format inside templates: %s."), data_str)); + EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid version.txt format inside the export templates file: %s."), data_str)); unzClose(pkg); return false; } @@ -232,32 +427,29 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ } if (version == String()) { - EditorNode::get_singleton()->show_warning(TTR("No version.txt found inside templates.")); + EditorNode::get_singleton()->show_warning(TTR("No version.txt found inside the export templates file.")); unzClose(pkg); return false; } - String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version); - DirAccessRef d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version); Error err = d->make_dir_recursive(template_path); if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Error creating path for templates:") + "\n" + template_path); + EditorNode::get_singleton()->show_warning(TTR("Error creating path for extracting templates:") + "\n" + template_path); unzClose(pkg); return false; } - ret = unzGoToFirstFile(pkg); - EditorProgress *p = nullptr; - if (p_use_progress) { + if (!p_skip_progress) { p = memnew(EditorProgress("ltask", TTR("Extracting Export Templates"), fc)); } fc = 0; - + ret = unzGoToFirstFile(pkg); while (ret == UNZ_OK) { - //get filename + // Get filename. unz_file_info info; char fname[16384]; unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0); @@ -274,7 +466,7 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ Vector<uint8_t> data; data.resize(info.uncompressed_size); - //read + // Read unzOpenCurrentFile(pkg); unzReadCurrentFile(pkg, data.ptrw(), data.size()); unzCloseCurrentFile(pkg); @@ -322,216 +514,116 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ if (p) { memdelete(p); } - unzClose(pkg); - _update_template_list(); + _update_template_status(); return true; } -void ExportTemplateManager::popup_manager() { - _update_template_list(); - popup_centered(Size2(400, 400) * EDSCALE); -} - -void ExportTemplateManager::ok_pressed() { - template_open->popup_file_dialog(); +void ExportTemplateManager::_uninstall_template(const String &p_version) { + uninstall_confirm->set_text(vformat(TTR("Remove templates for the version '%s'?"), p_version)); + uninstall_confirm->popup_centered(); + uninstall_version = p_version; } -void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { - if (p_status != HTTPRequest::RESULT_SUCCESS || p_code != 200) { - EditorNode::get_singleton()->show_warning(TTR("Error getting the list of mirrors.")); - return; - } +void ExportTemplateManager::_uninstall_template_confirmed() { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); - String mirror_str; - { - const uint8_t *r = p_data.ptr(); - mirror_str.parse_utf8((const char *)r, p_data.size()); - } + Error err = da->change_dir(templates_dir); + ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); + err = da->change_dir(uninstall_version); + ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir.plus_file(uninstall_version) + "'."); - template_list_state->hide(); - template_download_progress->hide(); + err = da->erase_contents_recursive(); + ERR_FAIL_COND_MSG(err != OK, "Could not remove all templates in '" + templates_dir.plus_file(uninstall_version) + "'."); - Variant r; - String errs; - int errline; - Error err = JSON::parse(mirror_str, r, errs, errline); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Error parsing JSON of mirror list. Please report this issue!")); - return; - } + da->change_dir(".."); + err = da->remove(uninstall_version); + ERR_FAIL_COND_MSG(err != OK, "Could not remove templates directory at '" + templates_dir.plus_file(uninstall_version) + "'."); - bool mirrors_found = false; + _update_template_status(); +} - Dictionary d = r; - if (d.has("mirrors")) { - Array mirrors = d["mirrors"]; - for (int i = 0; i < mirrors.size(); i++) { - Dictionary m = mirrors[i]; - ERR_CONTINUE(!m.has("url") || !m.has("name")); - LinkButton *lb = memnew(LinkButton); - lb->set_text(m["name"]); - lb->connect("pressed", callable_mp(this, &ExportTemplateManager::_begin_template_download), varray(m["url"])); - template_list->add_child(lb); - mirrors_found = true; - } +String ExportTemplateManager::_get_selected_mirror() const { + if (mirrors_list->get_item_count() == 1) { + return ""; } - if (!mirrors_found) { - EditorNode::get_singleton()->show_warning(TTR("No download links found for this version. Direct download is only available for official releases.")); - return; + int selected = mirrors_list->get_selected_id(); + if (selected == 0) { + // This is a special "best available" value; so pick the first available mirror from the rest of the list. + selected = 1; } + + return mirrors_list->get_item_metadata(selected); } -void ExportTemplateManager::_http_download_templates_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { - switch (p_status) { - case HTTPRequest::RESULT_CANT_RESOLVE: { - template_list_state->set_text(TTR("Can't resolve.")); - } break; - case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: - case HTTPRequest::RESULT_CONNECTION_ERROR: - case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: - case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: - case HTTPRequest::RESULT_CANT_CONNECT: { - template_list_state->set_text(TTR("Can't connect.")); - } break; - case HTTPRequest::RESULT_NO_RESPONSE: { - template_list_state->set_text(TTR("No response.")); - } break; - case HTTPRequest::RESULT_REQUEST_FAILED: { - template_list_state->set_text(TTR("Request Failed.")); - } break; - case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: { - template_list_state->set_text(TTR("Redirect Loop.")); +void ExportTemplateManager::_mirror_options_button_cbk(int p_id) { + switch (p_id) { + case VISIT_WEB_MIRROR: { + String mirror_url = _get_selected_mirror(); + if (mirror_url.is_empty()) { + EditorNode::get_singleton()->show_warning(TTR("There are no mirrors available.")); + return; + } + + OS::get_singleton()->shell_open(mirror_url); } break; - default: { - if (p_code != 200) { - template_list_state->set_text(TTR("Failed:") + " " + itos(p_code)); - } else { - String path = download_templates->get_download_file(); - template_list_state->set_text(TTR("Download Complete.")); - template_downloader->hide(); - bool ret = _install_from_file(path, false); - if (ret) { - // Clean up downloaded file. - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - Error err = da->remove(path); - if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Cannot remove temporary file:") + "\n" + path + "\n"); - } - } else { - EditorNode::get_singleton()->add_io_error(vformat(TTR("Templates installation failed.\nThe problematic templates archives can be found at '%s'."), path)); - } + + case COPY_MIRROR_URL: { + String mirror_url = _get_selected_mirror(); + if (mirror_url.is_empty()) { + EditorNode::get_singleton()->show_warning(TTR("There are no mirrors available.")); + return; } + + DisplayServer::get_singleton()->clipboard_set(mirror_url); } break; } - - set_process(false); } -void ExportTemplateManager::_begin_template_download(const String &p_url) { - if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { - OS::get_singleton()->shell_open(p_url); +void ExportTemplateManager::_installed_table_button_cbk(Object *p_item, int p_column, int p_id) { + TreeItem *ti = Object::cast_to<TreeItem>(p_item); + if (!ti) { return; } - for (int i = 0; i < template_list->get_child_count(); i++) { - BaseButton *b = Object::cast_to<BaseButton>(template_list->get_child(0)); - if (b) { - b->set_disabled(true); - } - } - - download_data.clear(); - download_templates->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz")); - download_templates->set_use_threads(true); + switch (p_id) { + case OPEN_TEMPLATE_FOLDER: { + String version_string = ti->get_text(0); + _open_template_folder(version_string); + } break; - Error err = download_templates->request(p_url); - if (err != OK) { - EditorNode::get_singleton()->show_warning(TTR("Error requesting URL:") + " " + p_url); - return; + case UNINSTALL_TEMPLATE: { + String version_string = ti->get_text(0); + _uninstall_template(version_string); + } break; } +} - set_process(true); - - template_list_state->show(); - template_download_progress->set_max(100); - template_download_progress->set_value(0); - template_download_progress->show(); - template_list_state->set_text(TTR("Connecting to Mirror...")); +void ExportTemplateManager::_open_template_folder(const String &p_version) { + const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); + OS::get_singleton()->shell_open("file://" + templates_dir.plus_file(p_version)); } -void ExportTemplateManager::_window_template_downloader_closed() { - download_templates->cancel_request(); +void ExportTemplateManager::popup_manager() { + _update_template_status(); + _refresh_mirrors(); + popup_centered(Size2(720, 280) * EDSCALE); } -void ExportTemplateManager::_notification(int p_what) { - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - if (!is_visible()) { - set_process(false); - } +void ExportTemplateManager::ok_pressed() { + if (!is_downloading_templates) { + hide(); + return; } - if (p_what == NOTIFICATION_PROCESS) { - update_countdown -= get_process_delta_time(); - if (update_countdown > 0) { - return; - } - update_countdown = 0.5; - String status; - bool errored = false; - - switch (download_templates->get_http_client_status()) { - case HTTPClient::STATUS_DISCONNECTED: - status = TTR("Disconnected"); - errored = true; - break; - case HTTPClient::STATUS_RESOLVING: - status = TTR("Resolving"); - break; - case HTTPClient::STATUS_CANT_RESOLVE: - status = TTR("Can't Resolve"); - errored = true; - break; - case HTTPClient::STATUS_CONNECTING: - status = TTR("Connecting..."); - break; - case HTTPClient::STATUS_CANT_CONNECT: - status = TTR("Can't Connect"); - errored = true; - break; - case HTTPClient::STATUS_CONNECTED: - status = TTR("Connected"); - break; - case HTTPClient::STATUS_REQUESTING: - status = TTR("Requesting..."); - break; - case HTTPClient::STATUS_BODY: - status = TTR("Downloading"); - if (download_templates->get_body_size() > 0) { - status += " " + String::humanize_size(download_templates->get_downloaded_bytes()) + "/" + String::humanize_size(download_templates->get_body_size()); - template_download_progress->set_max(download_templates->get_body_size()); - template_download_progress->set_value(download_templates->get_downloaded_bytes()); - } else { - status += " " + String::humanize_size(download_templates->get_downloaded_bytes()); - } - break; - case HTTPClient::STATUS_CONNECTION_ERROR: - status = TTR("Connection Error"); - errored = true; - break; - case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: - status = TTR("SSL Handshake Error"); - errored = true; - break; - } + hide_dialog_accept->popup_centered(); +} - template_list_state->set_text(status); - if (errored) { - set_process(false); - } - } +void ExportTemplateManager::_hide_dialog() { + hide(); } bool ExportTemplateManager::can_install_android_template() { @@ -643,72 +735,246 @@ Error ExportTemplateManager::install_android_template() { return OK; } -void ExportTemplateManager::_bind_methods() { -} +void ExportTemplateManager::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + current_value->add_theme_font_override("font", get_theme_font("main", "EditorFonts")); + current_missing_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); + current_installed_label->add_theme_color_override("font_color", get_theme_color("disabled_font_color", "Editor")); + + mirror_options_button->set_icon(get_theme_icon("GuiTabMenu", "EditorIcons")); + } break; -ExportTemplateManager::ExportTemplateManager() { - VBoxContainer *main_vb = memnew(VBoxContainer); - add_child(main_vb); + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible()) { + set_process(false); + } else if (is_visible() && is_downloading_templates) { + set_process(true); + } + } break; - current_hb = memnew(HBoxContainer); - main_vb->add_margin_child(TTR("Current Version:"), current_hb, false); + case NOTIFICATION_PROCESS: { + update_countdown -= get_process_delta_time(); + if (update_countdown > 0) { + return; + } + update_countdown = 0.5; - installed_scroll = memnew(ScrollContainer); - main_vb->add_margin_child(TTR("Other Installed Versions:"), installed_scroll, true); + String status; + int downloaded_bytes; + int total_bytes; + bool success = _humanize_http_status(download_templates, &status, &downloaded_bytes, &total_bytes); - installed_vb = memnew(VBoxContainer); - installed_scroll->add_child(installed_vb); - installed_scroll->set_enable_v_scroll(true); - installed_scroll->set_enable_h_scroll(false); - installed_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + if (downloaded_bytes >= 0) { + if (total_bytes > 0) { + _set_current_progress_value(float(downloaded_bytes) / total_bytes, status); + } else { + _set_current_progress_value(0, status); + } + } else { + _set_current_progress_status(status); + } - get_cancel_button()->set_text(TTR("Close")); - get_ok_button()->set_text(TTR("Install From File")); + if (!success) { + set_process(false); + } + } break; - remove_confirm = memnew(ConfirmationDialog); - remove_confirm->set_title(TTR("Remove Template")); - add_child(remove_confirm); - remove_confirm->connect("confirmed", callable_mp(this, &ExportTemplateManager::_uninstall_template_confirm)); + case NOTIFICATION_WM_CLOSE_REQUEST: { + // This won't stop the window from closing, but will show the alert if the download is active. + ok_pressed(); + } break; + } +} - template_open = memnew(FileDialog); - template_open->set_title(TTR("Select Template File")); - template_open->add_filter("*.tpz ; " + TTR("Godot Export Templates")); - template_open->set_access(FileDialog::ACCESS_FILESYSTEM); - template_open->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); - template_open->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_from_file), varray(true)); - add_child(template_open); +void ExportTemplateManager::_bind_methods() { +} +ExportTemplateManager::ExportTemplateManager() { set_title(TTR("Export Template Manager")); set_hide_on_ok(false); + get_ok_button()->set_text(TTR("Close")); + + // Downloadable export templates are only available for stable and official alpha/beta/RC builds + // (which always have a number following their status, e.g. "alpha1"). + // Therefore, don't display download-related features when using a development version + // (whose builds aren't numbered). + downloads_available = + String(VERSION_STATUS) != String("dev") && + String(VERSION_STATUS) != String("alpha") && + String(VERSION_STATUS) != String("beta") && + String(VERSION_STATUS) != String("rc"); + + VBoxContainer *main_vb = memnew(VBoxContainer); + add_child(main_vb); + + // Current version controls. + HBoxContainer *current_hb = memnew(HBoxContainer); + main_vb->add_child(current_hb); + + Label *current_label = memnew(Label); + current_label->set_text(TTR("Current Version:")); + current_hb->add_child(current_label); + + current_value = memnew(Label); + current_hb->add_child(current_value); + + // Current version statuses. + // Status: Current version is missing. + current_missing_label = memnew(Label); + current_missing_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + current_missing_label->set_align(Label::ALIGN_RIGHT); + current_missing_label->set_text(TTR("Export templates are missing. Download them or install from a file.")); + current_hb->add_child(current_missing_label); + + // Status: Current version is installed. + current_installed_label = memnew(Label); + current_installed_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + current_installed_label->set_align(Label::ALIGN_RIGHT); + current_installed_label->set_text(TTR("Export templates are installed and ready to be used.")); + current_hb->add_child(current_installed_label); + current_installed_label->hide(); + + // Currently installed template. + current_installed_hb = memnew(HBoxContainer); + main_vb->add_child(current_installed_hb); + + current_installed_path = memnew(LineEdit); + current_installed_path->set_editable(false); + current_installed_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + current_installed_hb->add_child(current_installed_path); + + current_open_button = memnew(Button); + current_open_button->set_text(TTR("Open Folder")); + current_open_button->set_tooltip(TTR("Open the folder containing installed templates for the current version.")); + current_installed_hb->add_child(current_open_button); + current_open_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_open_template_folder), varray(VERSION_FULL_CONFIG)); + + current_uninstall_button = memnew(Button); + current_uninstall_button->set_text(TTR("Uninstall")); + current_uninstall_button->set_tooltip(TTR("Uninstall templates for the current version.")); + current_installed_hb->add_child(current_uninstall_button); + current_uninstall_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_uninstall_template), varray(VERSION_FULL_CONFIG)); + + main_vb->add_child(memnew(HSeparator)); + + // Download and install section. + HBoxContainer *install_templates_hb = memnew(HBoxContainer); + main_vb->add_child(install_templates_hb); + + // Download and install buttons are available. + install_options_vb = memnew(VBoxContainer); + install_options_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + install_templates_hb->add_child(install_options_vb); + + HBoxContainer *download_install_hb = memnew(HBoxContainer); + install_options_vb->add_child(download_install_hb); + + Label *mirrors_label = memnew(Label); + mirrors_label->set_text(TTR("Download from:")); + download_install_hb->add_child(mirrors_label); + + mirrors_list = memnew(OptionButton); + mirrors_list->set_custom_minimum_size(Size2(280, 0) * EDSCALE); + download_install_hb->add_child(mirrors_list); + mirrors_list->add_item(TTR("Best available mirror"), 0); + + request_mirrors = memnew(HTTPRequest); + mirrors_list->add_child(request_mirrors); + request_mirrors->connect("request_completed", callable_mp(this, &ExportTemplateManager::_refresh_mirrors_completed)); + + mirror_options_button = memnew(MenuButton); + mirror_options_button->get_popup()->add_item("Open in Web Browser", VISIT_WEB_MIRROR); + mirror_options_button->get_popup()->add_item("Copy Mirror URL", COPY_MIRROR_URL); + download_install_hb->add_child(mirror_options_button); + mirror_options_button->get_popup()->connect("id_pressed", callable_mp(this, &ExportTemplateManager::_mirror_options_button_cbk)); + + download_install_hb->add_spacer(); + + Button *download_current_button = memnew(Button); + download_current_button->set_text(TTR("Download and Install")); + download_current_button->set_tooltip(TTR("Download and install templates for the current version from the best possible mirror.")); + download_install_hb->add_child(download_current_button); + download_current_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_download_current)); + + // Update downloads buttons to prevent unsupported downloads. + if (!downloads_available) { + download_current_button->set_disabled(true); + download_current_button->set_tooltip(TTR("Official export templates aren't available for development builds.")); + } - request_mirror = memnew(HTTPRequest); - add_child(request_mirror); - request_mirror->connect("request_completed", callable_mp(this, &ExportTemplateManager::_http_download_mirror_completed)); + HBoxContainer *install_file_hb = memnew(HBoxContainer); + install_file_hb->set_alignment(BoxContainer::ALIGN_END); + install_options_vb->add_child(install_file_hb); + + install_file_button = memnew(Button); + install_file_button->set_text(TTR("Install from File")); + install_file_button->set_tooltip(TTR("Install templates from a local file.")); + install_file_hb->add_child(install_file_button); + install_file_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_install_file)); + + // Templates are being downloaded; buttons unavailable. + download_progress_hb = memnew(HBoxContainer); + download_progress_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + install_templates_hb->add_child(download_progress_hb); + download_progress_hb->hide(); + + download_progress_bar = memnew(ProgressBar); + download_progress_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); + download_progress_bar->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + download_progress_bar->set_min(0); + download_progress_bar->set_max(1); + download_progress_bar->set_value(0); + download_progress_bar->set_step(0.01); + download_progress_hb->add_child(download_progress_bar); + + download_progress_label = memnew(Label); + download_progress_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + download_progress_hb->add_child(download_progress_label); + + Button *download_cancel_button = memnew(Button); + download_cancel_button->set_text(TTR("Cancel")); + download_cancel_button->set_tooltip(TTR("Cancel the download of the templates.")); + download_progress_hb->add_child(download_cancel_button); + download_cancel_button->connect("pressed", callable_mp(this, &ExportTemplateManager::_cancel_template_download)); download_templates = memnew(HTTPRequest); - add_child(download_templates); - download_templates->connect("request_completed", callable_mp(this, &ExportTemplateManager::_http_download_templates_completed)); - - template_downloader = memnew(AcceptDialog); - template_downloader->set_title(TTR("Download Templates")); - template_downloader->get_ok_button()->set_text(TTR("Close")); - template_downloader->set_exclusive(true); - add_child(template_downloader); - template_downloader->connect("cancelled", callable_mp(this, &ExportTemplateManager::_window_template_downloader_closed)); - - VBoxContainer *vbc = memnew(VBoxContainer); - template_downloader->add_child(vbc); - ScrollContainer *sc = memnew(ScrollContainer); - sc->set_custom_minimum_size(Size2(400, 200) * EDSCALE); - vbc->add_margin_child(TTR("Select mirror from list: (Shift+Click: Open in Browser)"), sc); - template_list = memnew(VBoxContainer); - sc->add_child(template_list); - sc->set_enable_v_scroll(true); - sc->set_enable_h_scroll(false); - template_list_state = memnew(Label); - vbc->add_child(template_list_state); - template_download_progress = memnew(ProgressBar); - vbc->add_child(template_download_progress); - - update_countdown = 0; + install_templates_hb->add_child(download_templates); + download_templates->connect("request_completed", callable_mp(this, &ExportTemplateManager::_download_template_completed)); + + main_vb->add_child(memnew(HSeparator)); + + // Other installed templates table. + HBoxContainer *installed_versions_hb = memnew(HBoxContainer); + main_vb->add_child(installed_versions_hb); + Label *installed_label = memnew(Label); + installed_label->set_text(TTR("Other Installed Versions:")); + installed_versions_hb->add_child(installed_label); + + installed_table = memnew(Tree); + installed_table->set_hide_root(true); + installed_table->set_custom_minimum_size(Size2(0, 100) * EDSCALE); + installed_table->set_v_size_flags(Control::SIZE_EXPAND_FILL); + main_vb->add_child(installed_table); + installed_table->connect("button_pressed", callable_mp(this, &ExportTemplateManager::_installed_table_button_cbk)); + + // Dialogs. + uninstall_confirm = memnew(ConfirmationDialog); + uninstall_confirm->set_title(TTR("Uninstall Template")); + add_child(uninstall_confirm); + uninstall_confirm->connect("confirmed", callable_mp(this, &ExportTemplateManager::_uninstall_template_confirmed)); + + install_file_dialog = memnew(FileDialog); + install_file_dialog->set_title(TTR("Select Template File")); + install_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); + install_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + install_file_dialog->add_filter("*.tpz ; " + TTR("Godot Export Templates")); + install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected), varray(false)); + add_child(install_file_dialog); + + hide_dialog_accept = memnew(AcceptDialog); + hide_dialog_accept->set_text(TTR("The templates will continue to download.\nYou may experience a short editor freeze when they finish.")); + add_child(hide_dialog_accept); + hide_dialog_accept->connect("confirmed", callable_mp(this, &ExportTemplateManager::_hide_dialog)); } diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h index 3de74e17d8..f145c6c0f5 100644 --- a/editor/export_template_manager.h +++ b/editor/export_template_manager.h @@ -34,50 +34,87 @@ #include "editor/editor_settings.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" +#include "scene/gui/menu_button.h" #include "scene/gui/progress_bar.h" #include "scene/gui/scroll_container.h" #include "scene/main/http_request.h" class ExportTemplateVersion; -class ExportTemplateManager : public ConfirmationDialog { - GDCLASS(ExportTemplateManager, ConfirmationDialog); +class ExportTemplateManager : public AcceptDialog { + GDCLASS(ExportTemplateManager, AcceptDialog); + + bool current_version_exists = false; + bool downloads_available = true; + bool mirrors_available = false; + bool is_refreshing_mirrors = false; + bool is_downloading_templates = false; + float update_countdown = 0; + + Label *current_value; + Label *current_missing_label; + Label *current_installed_label; + + HBoxContainer *current_installed_hb; + LineEdit *current_installed_path; + Button *current_open_button; + Button *current_uninstall_button; + + VBoxContainer *install_options_vb; + OptionButton *mirrors_list; + + enum MirrorAction { + VISIT_WEB_MIRROR, + COPY_MIRROR_URL, + }; + + MenuButton *mirror_options_button; + HBoxContainer *download_progress_hb; + ProgressBar *download_progress_bar; + Label *download_progress_label; + HTTPRequest *download_templates; + Button *install_file_button; + HTTPRequest *request_mirrors; - AcceptDialog *template_downloader; - VBoxContainer *template_list; - Label *template_list_state; - ProgressBar *template_download_progress; + enum TemplatesAction { + OPEN_TEMPLATE_FOLDER, + UNINSTALL_TEMPLATE, + }; - ScrollContainer *installed_scroll; - VBoxContainer *installed_vb; - HBoxContainer *current_hb; - FileDialog *template_open; + Tree *installed_table; - ConfirmationDialog *remove_confirm; - String to_remove; + ConfirmationDialog *uninstall_confirm; + String uninstall_version; + FileDialog *install_file_dialog; + AcceptDialog *hide_dialog_accept; - HTTPRequest *request_mirror; - HTTPRequest *download_templates; + void _update_template_status(); - Vector<uint8_t> download_data; + void _download_current(); + void _download_template(const String &p_url, bool p_skip_check = false); + void _download_template_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); + void _cancel_template_download(); + void _refresh_mirrors(); + void _refresh_mirrors_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); - float update_countdown; + bool _humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes); + void _set_current_progress_status(const String &p_status, bool p_error = false); + void _set_current_progress_value(float p_value, const String &p_status); - void _update_template_list(); + void _install_file(); + bool _install_file_selected(const String &p_file, bool p_skip_progress = false); - void _download_template(const String &p_version); void _uninstall_template(const String &p_version); - void _uninstall_template_confirm(); + void _uninstall_template_confirmed(); - virtual void ok_pressed() override; - bool _install_from_file(const String &p_file, bool p_use_progress = true); + String _get_selected_mirror() const; + void _mirror_options_button_cbk(int p_id); + void _installed_table_button_cbk(Object *p_item, int p_column, int p_id); - void _http_download_mirror_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); - void _http_download_templates_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); + void _open_template_folder(const String &p_version); - void _begin_template_download(const String &p_url); - - void _window_template_downloader_closed(); + virtual void ok_pressed() override; + void _hide_dialog(); protected: void _notification(int p_what); diff --git a/editor/icons/2D.svg b/editor/icons/2D.svg index afb9f4b45f..fdd2e473e3 100644 --- a/editor/icons/2D.svg +++ b/editor/icons/2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.9844 1.002a1.0001 1.0001 0 0 0 -.69141.29102l-2 2a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l.29297-.29297v8.5859h8.5859l-.29297.29297a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l.29297.29297h-6.5859v-6.5859l.29297.29297a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-2-2a1.0001 1.0001 0 0 0 -.72266-.29102z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.984375 15a1 1 0 0 1 -.6914062-.291316l-2-2a1 1 0 0 1 0-1.414062 1 1 0 0 1 1.4140624 0l.2929688.292968v-8.5859371h8.585938l-.292969-.292969a1 1 0 0 1 0-1.414062 1 1 0 0 1 1.414062 0l2 2a1 1 0 0 1 0 1.414062l-2 2.0000002a1 1 0 0 1 -.720703.2910157 1 1 0 0 1 -.693359-.2910157 1 1 0 0 1 0-1.4140622l.292969-.292969h-6.585938v6.5859371l.2929688-.292968a1 1 0 0 1 1.4140624 0 1 1 0 0 1 0 1.414062l-2 2a1 1 0 0 1 -.7226562.291316z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/KinematicBody2D.svg b/editor/icons/CharacterBody2D.svg index b71fda9650..b71fda9650 100644 --- a/editor/icons/KinematicBody2D.svg +++ b/editor/icons/CharacterBody2D.svg diff --git a/editor/icons/KinematicBody3D.svg b/editor/icons/CharacterBody3D.svg index d0def4f14a..d0def4f14a 100644 --- a/editor/icons/KinematicBody3D.svg +++ b/editor/icons/CharacterBody3D.svg diff --git a/editor/icons/Gradient.svg b/editor/icons/Gradient.svg index 47dde294fc..99d3a871a6 100644 --- a/editor/icons/Gradient.svg +++ b/editor/icons/Gradient.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="10" x2="10" y1="1" y2="15"><stop offset="0" stop-color="#e0e0e0"/><stop offset="1" stop-color="#e0e0e0" stop-opacity="0"/></linearGradient><path d="m2 1c-.55228 0-1 .44772-1 1v12c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-12c0-.55228-.44772-1-1-1z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3 1c-1.1046 0-2 .8954299-2 1.9999999v10.0000001c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10.0000001c0-1.1046-.89543-1.9999999-2-1.9999999zm0 1.9999999h10v10.0000001h-10z"/><path d="m7.5 5.500001h1v1h-1z" stroke-width=".787342"/><path d="m3.5 3.5v9h3v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1h1v-1h-1v-1z" stroke-width="4.09116"/><g stroke-width=".787342"><path d="m7.5 3.5h1v1h-1z"/><path d="m7.5 9.500001h1v1h-1z"/><path d="m7.5 7.500001h1v1h-1z"/><path d="m7.5 11.5h1v1h-1z"/><path d="m8.5 4.500001h1v1h-1z"/><path d="m8.5 6.500001h1v1h-1z"/><path d="m8.5 8.500002h1v1h-1z"/><path d="m8.5 10.500002h1v1h-1z"/></g></g></svg> diff --git a/editor/icons/GradientTexture.svg b/editor/icons/GradientTexture.svg index ec4c4546e1..fa03e69805 100644 --- a/editor/icons/GradientTexture.svg +++ b/editor/icons/GradientTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="10" x2="10" y1="1" y2="15"><stop offset="0" stop-color="#e0e0e0"/><stop offset="1" stop-color="#e0e0e0" stop-opacity="0"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m2 1a1 1 0 0 0 -1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-12a1 1 0 0 0 -1-1zm1 2h10v8h-10z" fill="url(#a)" transform="translate(0 1036.4)"/><g fill="#e0e0e0"><path d="m6 1043.4h2v1h-2z"/><path d="m6 1044.4h2v2h-2z"/><path d="m4 1045.4h2v1h-2z"/><path d="m8 1044.4h2v2h-2z"/><path d="m10 1044.4h2v2h-2z"/><path d="m8 1042.4h3v2h-3z"/><path d="m9 1041.4h1v1h-1z"/><path d="m5 1044.4h1v1h-1z"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m12.5 10.5v-7h-3v1h-1v1h1v1h-1v1h1v1h-1v1h1v1zm-4-1h-1v1h1zm-1 0v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1zm0-1v-1h-1v1zm0-1h1v-1h-1z" stroke-width=".787342"/><path d="m2 1c-.552285 0-1 .4477153-1 1v12.000001c0 .552285.447715 1 1 1h11.999999c.552285 0 1-.447715 1-1v-12.000001c0-.5522847-.447715-1-1-1zm1 2.0000001h9.999999v8.0000009h-9.999999z" fill-opacity=".99608"/></g></svg> diff --git a/editor/icons/GuiRadioChecked.svg b/editor/icons/GuiRadioChecked.svg index 771337116d..65ef086c9a 100644 --- a/editor/icons/GuiRadioChecked.svg +++ b/editor/icons/GuiRadioChecked.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m15 8a7 7 0 0 1 -7 7 7 7 0 0 1 -7-7 7 7 0 0 1 7-7 7 7 0 0 1 7 7" fill-opacity=".188235" stroke-width="2.333333"/><path d="m12 8a4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" stroke-width="1.333333"/></g></svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8a7 7 0 0 1 -7 7 7 7 0 0 1 -7-7 7 7 0 0 1 7-7 7 7 0 0 1 7 7" fill="#699ce8" stroke-width="2.33333"/><path d="m12 8a4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 4 4" fill="#fff" stroke-width="1.33333"/></svg> diff --git a/editor/icons/BakedLightmap.svg b/editor/icons/LightmapGI.svg index 78f0a64a7b..78f0a64a7b 100644 --- a/editor/icons/BakedLightmap.svg +++ b/editor/icons/LightmapGI.svg diff --git a/editor/icons/BakedLightmapData.svg b/editor/icons/LightmapGIData.svg index f5dcfb618b..f5dcfb618b 100644 --- a/editor/icons/BakedLightmapData.svg +++ b/editor/icons/LightmapGIData.svg diff --git a/editor/icons/Occluder3D.svg b/editor/icons/Occluder3D.svg new file mode 100644 index 0000000000..850e2651af --- /dev/null +++ b/editor/icons/Occluder3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.90625 1a7 7 0 0 0 -1.2988281.1386719 4.5 4.5 0 0 1 3.3925781 4.3613281 4.5 4.5 0 0 1 -4.5 4.5 4.5 4.5 0 0 1 -4.359375-3.3886719 7 7 0 0 0 -.140625 1.3886719 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7 7 7 0 0 0 -.09375 0z" fill="#ffca5f" stroke-width=".365215"/></svg> diff --git a/editor/icons/OccluderInstance3D.svg b/editor/icons/OccluderInstance3D.svg new file mode 100644 index 0000000000..cc7ccc410f --- /dev/null +++ b/editor/icons/OccluderInstance3D.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.90625 1a7 7 0 0 0 -1.2988281.1386719 4.5 4.5 0 0 1 3.3925781 4.3613281 4.5 4.5 0 0 1 -4.5 4.5 4.5 4.5 0 0 1 -4.359375-3.3886719 7 7 0 0 0 -.140625 1.3886719 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7 7 7 0 0 0 -.09375 0z" fill="#fc7f7f" fill-opacity=".996078" stroke-width=".365215"/></svg> diff --git a/editor/icons/Quat.svg b/editor/icons/Quaternion.svg index cf29160ff4..cf29160ff4 100644 --- a/editor/icons/Quat.svg +++ b/editor/icons/Quaternion.svg diff --git a/editor/icons/GIProbe.svg b/editor/icons/VoxelGI.svg index f5e1025260..f5e1025260 100644 --- a/editor/icons/GIProbe.svg +++ b/editor/icons/VoxelGI.svg diff --git a/editor/icons/GIProbeData.svg b/editor/icons/VoxelGIData.svg index 5975115f4c..5975115f4c 100644 --- a/editor/icons/GIProbeData.svg +++ b/editor/icons/VoxelGIData.svg diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp index e38034dd8c..aa9700716d 100644 --- a/editor/import/collada.cpp +++ b/editor/import/collada.cpp @@ -50,8 +50,8 @@ String Collada::Effect::get_texture_path(const String &p_source, Collada &state) return state.state.image_map[image].path; } -Transform Collada::get_root_transform() const { - Transform unit_scale_transform; +Transform3D Collada::get_root_transform() const { + Transform3D unit_scale_transform; #ifndef COLLADA_IMPORT_SCALE_SCENE unit_scale_transform.scale(Vector3(state.unit_scale, state.unit_scale, state.unit_scale)); #endif @@ -74,8 +74,8 @@ static String _uri_to_id(const String &p_uri) { /** HELPER FUNCTIONS **/ -Transform Collada::fix_transform(const Transform &p_transform) { - Transform tr = p_transform; +Transform3D Collada::fix_transform(const Transform3D &p_transform) { + Transform3D tr = p_transform; #ifndef NO_UP_AXIS_SWAP @@ -102,8 +102,8 @@ Transform Collada::fix_transform(const Transform &p_transform) { //return state.matrix_fix * p_transform; } -static Transform _read_transform_from_array(const Vector<float> &array, int ofs = 0) { - Transform tr; +static Transform3D _read_transform_from_array(const Vector<float> &array, int ofs = 0) { + Transform3D tr; // i wonder why collada matrices are transposed, given that's opposed to opengl.. tr.basis.elements[0][0] = array[0 + ofs]; tr.basis.elements[0][1] = array[1 + ofs]; @@ -122,11 +122,11 @@ static Transform _read_transform_from_array(const Vector<float> &array, int ofs /* STRUCTURES */ -Transform Collada::Node::compute_transform(Collada &state) const { - Transform xform; +Transform3D Collada::Node::compute_transform(Collada &state) const { + Transform3D xform; for (int i = 0; i < xform_list.size(); i++) { - Transform xform_step; + Transform3D xform_step; const XForm &xf = xform_list[i]; switch (xf.op) { case XForm::OP_ROTATE: { @@ -165,11 +165,11 @@ Transform Collada::Node::compute_transform(Collada &state) const { return xform; } -Transform Collada::Node::get_transform() const { +Transform3D Collada::Node::get_transform() const { return default_transform; } -Transform Collada::Node::get_global_transform() const { +Transform3D Collada::Node::get_global_transform() const { if (parent) { return parent->get_global_transform() * default_transform; } else { @@ -201,14 +201,14 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const { if (keys[i].data.size() == 16) { //interpolate a matrix - Transform src = _read_transform_from_array(keys[i - 1].data); - Transform dst = _read_transform_from_array(keys[i].data); + Transform3D src = _read_transform_from_array(keys[i - 1].data); + Transform3D dst = _read_transform_from_array(keys[i].data); - Transform interp = c < 0.001 ? src : src.interpolate_with(dst, c); + Transform3D interp = c < 0.001 ? src : src.interpolate_with(dst, c); Vector<float> ret; ret.resize(16); - Transform tr; + Transform3D tr; // i wonder why collada matrices are transposed, given that's opposed to opengl.. ret.write[0] = interp.basis.elements[0][0]; ret.write[1] = interp.basis.elements[0][1]; @@ -410,10 +410,9 @@ Vector<String> Collada::_read_string_array(XMLParser &parser) { return array; } -Transform Collada::_read_transform(XMLParser &parser) { - if (parser.is_empty()) { - return Transform(); - } +Transform3D Collada::_read_transform(XMLParser &parser) { + if (parser.is_empty()) + return Transform3D(); Vector<String> array; while (parser.read() == OK) { @@ -429,7 +428,7 @@ Transform Collada::_read_transform(XMLParser &parser) { } } - ERR_FAIL_COND_V(array.size() != 16, Transform()); + ERR_FAIL_COND_V(array.size() != 16, Transform3D()); Vector<float> farr; farr.resize(16); for (int i = 0; i < 16; i++) { @@ -1197,7 +1196,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) { /* STORE REST MATRICES */ - Vector<Transform> rests; + Vector<Transform3D> rests; ERR_FAIL_COND(!skindata.joints.sources.has("JOINT")); ERR_FAIL_COND(!skindata.joints.sources.has("INV_BIND_MATRIX")); @@ -1214,7 +1213,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) { for (int i = 0; i < joint_source.sarray.size(); i++) { String name = joint_source.sarray[i]; - Transform xform = _read_transform_from_array(ibm_source.array, i * 16); //<- this is a mistake, it must be applied to vertices + Transform3D xform = _read_transform_from_array(ibm_source.array, i * 16); //<- this is a mistake, it must be applied to vertices xform.affine_invert(); // inverse for rest, because it's an inverse #ifdef COLLADA_IMPORT_SCALE_SCENE xform.origin *= state.unit_scale; @@ -2096,7 +2095,7 @@ void Collada::_merge_skeletons2(VisualScene *p_vscene) { NodeSkeleton *skeleton = nullptr; - for (Map<String, Transform>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) { + for (Map<String, Transform3D>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) { String name; if (!state.sid_to_node_map.has(F->key())) { @@ -2240,11 +2239,11 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L //this should be correct ERR_FAIL_COND_V(!state.skin_controller_data_map.has(ng->source), false); SkinControllerData &skin = state.skin_controller_data_map[ng->source]; - Transform skel_inv = sk->get_global_transform().affine_inverse(); + Transform3D skel_inv = sk->get_global_transform().affine_inverse(); p_node->default_transform = skel_inv * (skin.bind_shape /* p_node->get_global_transform()*/); // i honestly have no idea what to do with a previous model xform.. most exporters ignore it //make rests relative to the skeleton (they seem to be always relative to world) - for (Map<String, Transform>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) { + for (Map<String, Transform3D>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) { E->get() = skel_inv * E->get(); //make the bone rest local to the skeleton state.bone_rest_map[E->key()] = E->get(); // make it remember where the bone is globally, now that it's relative } @@ -2252,7 +2251,7 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L //but most exporters seem to work only if i do this.. //p_node->default_transform = p_node->get_global_transform(); - //p_node->default_transform=Transform(); //this seems to be correct, because bind shape makes the object local to the skeleton + //p_node->default_transform=Transform3D(); //this seems to be correct, because bind shape makes the object local to the skeleton p_node->ignore_anim = true; // collada may animate this later, if it does, then this is not supported (redo your original asset and don't animate the base mesh) p_node->parent = sk; //sk->children.push_back(0,p_node); //avoid INFINITE loop diff --git a/editor/import/collada.h b/editor/import/collada.h index 2c3f0a3006..5e38637504 100644 --- a/editor/import/collada.h +++ b/editor/import/collada.h @@ -182,7 +182,7 @@ public: String base; bool use_idrefs = false; - Transform bind_shape; + Transform3D bind_shape; struct Source { Vector<String> sarray; //maybe for names @@ -210,7 +210,7 @@ public: int count = 0; } weights; - Map<String, Transform> bone_rest_map; + Map<String, Transform3D> bone_rest_map; SkinControllerData() {} }; @@ -342,15 +342,15 @@ public: String empty_draw_type; bool noname = false; Vector<XForm> xform_list; - Transform default_transform; - Transform post_transform; + Transform3D default_transform; + Transform3D post_transform; Vector<Node *> children; Node *parent = nullptr; - Transform compute_transform(Collada &state) const; - Transform get_global_transform() const; - Transform get_transform() const; + Transform3D compute_transform(Collada &state) const; + Transform3D get_global_transform() const; + Transform3D get_transform() const; bool ignore_anim = false; @@ -497,7 +497,7 @@ public: Map<String, String> sid_to_node_map; //Map<String,NodeJoint*> bone_map; - Map<String, Transform> bone_rest_map; + Map<String, Transform3D> bone_rest_map; String local_path; String root_visual_scene; @@ -517,9 +517,9 @@ public: Collada(); - Transform fix_transform(const Transform &p_transform); + Transform3D fix_transform(const Transform3D &p_transform); - Transform get_root_transform() const; + Transform3D get_root_transform() const; int get_uv_channel(String p_name); @@ -557,7 +557,7 @@ private: // private stuff Variant _parse_param(XMLParser &parser); Vector<float> _read_float_array(XMLParser &parser); Vector<String> _read_string_array(XMLParser &parser); - Transform _read_transform(XMLParser &parser); + Transform3D _read_transform(XMLParser &parser); String _read_empty_draw_type(XMLParser &parser); void _joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index d3183e5a8d..dc1bd38a99 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -87,7 +87,7 @@ struct ColladaImport { Error _create_scene(Collada::Node *p_node, Node3D *p_parent); Error _create_resources(Collada::Node *p_node, bool p_use_compression); Error _create_material(const String &p_target); - Error _create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes = Vector<Ref<EditorSceneImporterMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false); + Error _create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes = Vector<Ref<EditorSceneImporterMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false); Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, bool p_use_compression = false); void _fix_param_animation_tracks(); void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks); @@ -300,7 +300,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) { nm.node = node; node_map[p_node->id] = nm; node_name_map[node->get_name()] = p_node->id; - Transform xf = p_node->default_transform; + Transform3D xf = p_node->default_transform; xf = collada.fix_transform(xf) * p_node->post_transform; node->set_transform(xf); @@ -457,7 +457,7 @@ Error ColladaImport::_create_material(const String &p_target) { return OK; } -Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) { +Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) { bool local_xform_mirror = p_local_xform.basis.determinant() < 0; if (p_morph_data) { @@ -811,7 +811,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor if (has_weights) { //if skeleton, localize - Transform local_xform = p_local_xform; + Transform3D local_xform = p_local_xform; for (int i = 0; i < vertex_array.size(); i++) { vertex_array.write[i].vertex = local_xform.xform(vertex_array[i].vertex); vertex_array.write[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized(); @@ -1037,7 +1037,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres Collada::SkinControllerData *skin = nullptr; Collada::MorphControllerData *morph = nullptr; String meshid; - Transform apply_xform; + Transform3D apply_xform; Vector<int> bone_remap; Vector<Ref<EditorSceneImporterMesh>> morphs; @@ -1073,9 +1073,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres if (apply_mesh_xform_to_vertices) { apply_xform = collada.fix_transform(p_node->default_transform); - node->set_transform(Transform()); + node->set_transform(Transform3D()); } else { - apply_xform = Transform(); + apply_xform = Transform3D(); } ERR_FAIL_COND_V(!skin->weights.sources.has("JOINT"), ERR_INVALID_DATA); @@ -1461,7 +1461,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones continue; } - animation->add_track(Animation::TYPE_TRANSFORM); + animation->add_track(Animation::TYPE_TRANSFORM3D); int track = animation->get_track_count() - 1; animation->track_set_path(track, path); animation->track_set_imported(track, true); //helps merging later @@ -1530,7 +1530,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones } } - Transform xform = cn->compute_transform(collada); + Transform3D xform = cn->compute_transform(collada); xform = collada.fix_transform(xform) * cn->post_transform; if (nm.bone >= 0) { @@ -1545,7 +1545,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones Vector3 s = xform.basis.get_scale(); bool singular_matrix = Math::is_equal_approx(s.x, 0.0f) || Math::is_equal_approx(s.y, 0.0f) || Math::is_equal_approx(s.z, 0.0f); - Quat q = singular_matrix ? Quat() : xform.basis.get_rotation_quat(); + Quaternion q = singular_matrix ? Quaternion() : xform.basis.get_rotation_quaternion(); Vector3 l = xform.origin; animation->transform_track_insert_key(track, snapshots[i], l, q, s); @@ -1584,19 +1584,19 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones continue; } - animation->add_track(Animation::TYPE_TRANSFORM); + animation->add_track(Animation::TYPE_TRANSFORM3D); int track = animation->get_track_count() - 1; animation->track_set_path(track, path); animation->track_set_imported(track, true); //helps merging later - Transform xform = cn->compute_transform(collada); + Transform3D xform = cn->compute_transform(collada); xform = collada.fix_transform(xform) * cn->post_transform; xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; Vector3 s = xform.basis.get_scale(); bool singular_matrix = Math::is_equal_approx(s.x, 0.0f) || Math::is_equal_approx(s.y, 0.0f) || Math::is_equal_approx(s.z, 0.0f); - Quat q = singular_matrix ? Quat() : xform.basis.get_rotation_quat(); + Quaternion q = singular_matrix ? Quaternion() : xform.basis.get_rotation_quaternion(); Vector3 l = xform.origin; animation->transform_track_insert_key(track, 0, l, q, s); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 96002400f3..b589a6aaa0 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -433,7 +433,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E p_node->replace_by(rigid_body); rigid_body->set_transform(mi->get_transform()); p_node = rigid_body; - mi->set_transform(Transform()); + mi->set_transform(Transform3D()); rigid_body->add_child(mi); mi->set_owner(rigid_body->get_owner()); @@ -632,7 +632,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< p_node->replace_by(rigid_body); rigid_body->set_transform(mi->get_transform()); p_node = rigid_body; - mi->set_transform(Transform()); + mi->set_transform(Transform3D()); rigid_body->add_child(mi); mi->set_owner(rigid_body->get_owner()); base = rigid_body; @@ -856,8 +856,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ new_anim->track_set_path(dtrack, default_anim->track_get_path(j)); if (kt > (from + 0.01) && k > 0) { - if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) { - Quat q; + if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) { + Quaternion q; Vector3 p; Vector3 s; default_anim->transform_track_interpolate(j, from, &p, &q, &s); @@ -870,8 +870,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } } - if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) { - Quat q; + if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) { + Quaternion q; Vector3 p; Vector3 s; default_anim->transform_track_get_key(j, k, &p, &q, &s); @@ -884,8 +884,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ } if (dtrack != -1 && kt >= to) { - if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) { - Quat q; + if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) { + Quaternion q; Vector3 p; Vector3 s; default_anim->transform_track_interpolate(j, to, &p, &q, &s); @@ -902,8 +902,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ new_anim->add_track(default_anim->track_get_type(j)); dtrack = new_anim->get_track_count() - 1; new_anim->track_set_path(dtrack, default_anim->track_get_path(j)); - if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) { - Quat q; + if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) { + Quaternion q; Vector3 p; Vector3 s; default_anim->transform_track_interpolate(j, from, &p, &q, &s); @@ -1209,7 +1209,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } if (bake_lightmaps) { - Transform xf; + Transform3D xf; Node3D *n = src_mesh_node; while (n) { xf = n->get_transform() * xf; diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index de8031af35..74b30f4e3e 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -208,7 +208,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.svgz,*.tga,*.webp"), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/invert_color"), false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0)); @@ -388,7 +388,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String uint32_t mipmap_limit = int(mipmaps ? int(p_options["mipmaps/limit"]) : int(-1)); bool fix_alpha_border = p_options["process/fix_alpha_border"]; bool premult_alpha = p_options["process/premult_alpha"]; - bool invert_color = p_options["process/invert_color"]; + bool normal_map_invert_y = p_options["process/normal_map_invert_y"]; bool stream = p_options["compress/streamed"]; int size_limit = p_options["process/size_limit"]; bool hdr_as_srgb = p_options["process/HDR_as_SRGB"]; @@ -444,13 +444,18 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String image->premultiply_alpha(); } - if (invert_color) { - int height = image->get_height(); - int width = image->get_width(); + if (normal_map_invert_y) { + // Inverting the green channel can be used to flip a normal map's direction. + // There's no standard when it comes to normal map Y direction, so this is + // sometimes needed when using a normal map exported from another program. + // See <http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates>. + const int height = image->get_height(); + const int width = image->get_width(); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - image->set_pixel(i, j, image->get_pixel(i, j).inverted()); + const Color color = image->get_pixel(i, j); + image->set_pixel(i, j, Color(color.r, 1 - color.g, color.b)); } } } diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 488c124c28..600f3fe2f0 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -317,7 +317,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) { if (mesh_node && mesh_node->get_mesh().is_valid()) { _fill_mesh(scene_tree, mesh_node->get_mesh(), item); - Transform accum_xform; + Transform3D accum_xform; Node3D *base = mesh_node; while (base) { accum_xform = base->get_transform() * accum_xform; @@ -379,7 +379,7 @@ void SceneImportSettings::_update_camera() { camera->set_orthogonal(camera_size * zoom, 0.0001, camera_size * 2); - Transform xf; + Transform3D xf; xf.basis = Basis(Vector3(0, 1, 0), rot_y) * Basis(Vector3(1, 0, 0), rot_x); xf.origin = center; xf.translate(0, 0, camera_size); @@ -493,7 +493,7 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) { Ref<Mesh> base_mesh = mi->get_mesh(); if (base_mesh.is_valid()) { AABB aabb = base_mesh->get_aabb(); - Transform aabb_xf; + Transform3D aabb_xf; aabb_xf.basis.scale(aabb.size); aabb_xf.origin = aabb.position; @@ -1099,7 +1099,7 @@ SceneImportSettings::SceneImportSettings() { camera->make_current(); light = memnew(DirectionalLight3D); - light->set_transform(Transform().looking_at(Vector3(-1, -2, -0.6), Vector3(0, 1, 0))); + light->set_transform(Transform3D().looking_at(Vector3(-1, -2, -0.6), Vector3(0, 1, 0))); base_viewport->add_child(light); light->set_shadow(true); diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index fa1a027a8d..bf17ea7bca 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -612,7 +612,7 @@ struct EditorSceneImporterMeshLightmapSurface { String name; }; -Error EditorSceneImporterMesh::lightmap_unwrap_cached(const Transform &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache) { +Error EditorSceneImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache) { 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."); @@ -628,7 +628,7 @@ Error EditorSceneImporterMesh::lightmap_unwrap_cached(const Transform &p_base_tr Basis basis = p_base_transform.get_basis(); Vector3 scale = Vector3(basis.get_axis(0).length(), basis.get_axis(1).length(), basis.get_axis(2).length()); - Transform transform; + Transform3D transform; transform.scale(scale); Basis normal_basis = transform.basis.inverse().transposed(); diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h index c00339a620..2488de7ed0 100644 --- a/editor/import/scene_importer_mesh.h +++ b/editor/import/scene_importer_mesh.h @@ -106,7 +106,7 @@ public: Vector<Ref<Shape3D>> convex_decompose() const; Ref<Shape3D> create_trimesh_shape() const; Ref<NavigationMesh> create_navigation_mesh(); - Error lightmap_unwrap_cached(const Transform &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache); + Error lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache); void set_lightmap_size_hint(const Size2i &p_size); Size2i get_lightmap_size_hint() const; diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 6265dfc2e4..e8c01d0e0c 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -42,6 +42,14 @@ void InspectorDock::_menu_option(int p_option) { case COLLAPSE_ALL: { _menu_collapseall(); } break; + + case RESOURCE_SAVE: { + _save_resource(false); + } break; + case RESOURCE_SAVE_AS: { + _save_resource(true); + } break; + case RESOURCE_MAKE_BUILT_IN: { _unref_resource(); } break; @@ -52,13 +60,6 @@ void InspectorDock::_menu_option(int p_option) { _paste_resource(); } break; - case RESOURCE_SAVE: { - _save_resource(false); - } break; - case RESOURCE_SAVE_AS: { - _save_resource(true); - } break; - case OBJECT_REQUEST_HELP: { if (current) { editor->set_visible_editor(EditorNode::EDITOR_SCRIPT); @@ -313,7 +314,7 @@ void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_valu AnimationPlayerEditor::singleton->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance); } -void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform &p_key) { +void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key) { Node3D *s = Object::cast_to<Node3D>(sp); if (!s) { return; @@ -335,9 +336,16 @@ void InspectorDock::_notification(int p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { set_theme(editor->get_gui_base()->get_theme()); + resource_new_button->set_icon(get_theme_icon("New", "EditorIcons")); resource_load_button->set_icon(get_theme_icon("Load", "EditorIcons")); resource_save_button->set_icon(get_theme_icon("Save", "EditorIcons")); + resource_extra_button->set_icon(get_theme_icon("GuiTabMenu", "EditorIcons")); + + PopupMenu *resource_extra_popup = resource_extra_button->get_popup(); + resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_EDIT_CLIPBOARD), get_theme_icon("ActionPaste", "EditorIcons")); + resource_extra_popup->set_item_icon(resource_extra_popup->get_item_index(RESOURCE_COPY), get_theme_icon("ActionCopy", "EditorIcons")); + if (is_layout_rtl()) { backward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); forward_button->set_icon(get_theme_icon("Back", "EditorIcons")); @@ -345,6 +353,7 @@ void InspectorDock::_notification(int p_what) { backward_button->set_icon(get_theme_icon("Back", "EditorIcons")); forward_button->set_icon(get_theme_icon("Forward", "EditorIcons")); } + history_menu->set_icon(get_theme_icon("History", "EditorIcons")); object_menu->set_icon(get_theme_icon("Tools", "EditorIcons")); warning->set_icon(get_theme_icon("NodeWarning", "EditorIcons")); @@ -403,12 +412,7 @@ void InspectorDock::update(Object *p_object) { object_menu->set_disabled(true); warning->hide(); search->set_editable(false); - - editor_path->set_disabled(true); - editor_path->set_text(""); - editor_path->set_tooltip(""); - editor_path->set_icon(nullptr); - + editor_path->clear_path(); return; } @@ -417,35 +421,28 @@ void InspectorDock::update(Object *p_object) { object_menu->set_disabled(false); search->set_editable(true); - editor_path->set_disabled(false); + editor_path->enable_path(); + resource_save_button->set_disabled(!is_resource); + open_docs_button->set_visible(is_resource || is_node); + + PopupMenu *resource_extra_popup = resource_extra_button->get_popup(); + resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_COPY), !is_resource); + resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_MAKE_BUILT_IN), !is_resource); PopupMenu *p = object_menu->get_popup(); p->clear(); - p->add_shortcut(ED_SHORTCUT("property_editor/expand_all", TTR("Expand All Properties")), EXPAND_ALL); - p->add_shortcut(ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All Properties")), COLLAPSE_ALL); - p->add_separator(); - if (is_resource) { - p->add_item(TTR("Save"), RESOURCE_SAVE); - p->add_item(TTR("Save As..."), RESOURCE_SAVE_AS); - p->add_separator(); - } - p->add_shortcut(ED_SHORTCUT("property_editor/copy_params", TTR("Copy Params")), OBJECT_COPY_PARAMS); - p->add_shortcut(ED_SHORTCUT("property_editor/paste_params", TTR("Paste Params")), OBJECT_PASTE_PARAMS); + p->add_icon_shortcut(get_theme_icon("GuiTreeArrowDown", "EditorIcons"), ED_SHORTCUT("property_editor/expand_all", TTR("Expand All")), EXPAND_ALL); + p->add_icon_shortcut(get_theme_icon("GuiTreeArrowRight", "EditorIcons"), ED_SHORTCUT("property_editor/collapse_all", TTR("Collapse All")), COLLAPSE_ALL); p->add_separator(); - p->add_shortcut(ED_SHORTCUT("property_editor/paste_resource", TTR("Edit Resource Clipboard")), RESOURCE_EDIT_CLIPBOARD); - if (is_resource) { - p->add_shortcut(ED_SHORTCUT("property_editor/copy_resource", TTR("Copy Resource")), RESOURCE_COPY); - p->add_shortcut(ED_SHORTCUT("property_editor/unref_resource", TTR("Make Built-In")), RESOURCE_MAKE_BUILT_IN); - } + p->add_shortcut(ED_SHORTCUT("property_editor/copy_params", TTR("Copy Properties")), OBJECT_COPY_PARAMS); + p->add_shortcut(ED_SHORTCUT("property_editor/paste_params", TTR("Paste Properties")), OBJECT_PASTE_PARAMS); if (is_resource || is_node) { p->add_separator(); p->add_shortcut(ED_SHORTCUT("property_editor/make_subresources_unique", TTR("Make Sub-Resources Unique")), OBJECT_UNIQUE_RESOURCES); - p->add_separator(); - p->add_icon_shortcut(get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("property_editor/open_help", TTR("Open in Help")), OBJECT_REQUEST_HELP); } List<MethodInfo> methods; @@ -525,6 +522,17 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { resource_save_button->set_focus_mode(Control::FOCUS_NONE); resource_save_button->set_disabled(true); + resource_extra_button = memnew(MenuButton); + resource_extra_button->set_icon(get_theme_icon("GuiTabMenu", "EditorIcons")); + general_options_hb->add_child(resource_extra_button); + resource_extra_button->get_popup()->add_icon_shortcut(get_theme_icon("ActionPaste", "EditorIcons"), ED_SHORTCUT("property_editor/paste_resource", TTR("Edit Resource from Clipboard")), RESOURCE_EDIT_CLIPBOARD); + resource_extra_button->get_popup()->add_icon_shortcut(get_theme_icon("ActionCopy", "EditorIcons"), ED_SHORTCUT("property_editor/copy_resource", TTR("Copy Resource")), RESOURCE_COPY); + resource_extra_button->get_popup()->set_item_disabled(1, true); + resource_extra_button->get_popup()->add_separator(); + resource_extra_button->get_popup()->add_shortcut(ED_SHORTCUT("property_editor/unref_resource", TTR("Make Resource Built-In")), RESOURCE_MAKE_BUILT_IN); + resource_extra_button->get_popup()->set_item_disabled(3, true); + resource_extra_button->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_menu_option)); + general_options_hb->add_spacer(); backward_button = memnew(Button); @@ -558,31 +566,42 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) { history_menu->connect("about_to_popup", callable_mp(this, &InspectorDock::_prepare_history)); history_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_select_history)); - HBoxContainer *node_info_hb = memnew(HBoxContainer); - add_child(node_info_hb); - + HBoxContainer *subresource_hb = memnew(HBoxContainer); + add_child(subresource_hb); editor_path = memnew(EditorPath(editor->get_editor_history())); editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); - node_info_hb->add_child(editor_path); + subresource_hb->add_child(editor_path); - object_menu = memnew(MenuButton); - object_menu->set_shortcut_context(this); - object_menu->set_icon(get_theme_icon("Tools", "EditorIcons")); - node_info_hb->add_child(object_menu); - object_menu->set_tooltip(TTR("Object properties.")); - object_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_menu_option)); + open_docs_button = memnew(Button); + open_docs_button->set_flat(true); + open_docs_button->set_visible(false); + open_docs_button->set_tooltip(TTR("Open documentation for this object.")); + open_docs_button->set_icon(get_theme_icon("HelpSearch", "EditorIcons")); + open_docs_button->set_shortcut(ED_SHORTCUT("property_editor/open_help", TTR("Open Documentation"))); + subresource_hb->add_child(open_docs_button); + open_docs_button->connect("pressed", callable_mp(this, &InspectorDock::_menu_option), varray(OBJECT_REQUEST_HELP)); new_resource_dialog = memnew(CreateDialog); editor->get_gui_base()->add_child(new_resource_dialog); new_resource_dialog->set_base_type("Resource"); new_resource_dialog->connect("create", callable_mp(this, &InspectorDock::_resource_created)); + HBoxContainer *property_tools_hb = memnew(HBoxContainer); + add_child(property_tools_hb); + search = memnew(LineEdit); search->set_h_size_flags(Control::SIZE_EXPAND_FILL); search->set_placeholder(TTR("Filter properties")); search->set_right_icon(get_theme_icon("Search", "EditorIcons")); search->set_clear_button_enabled(true); - add_child(search); + property_tools_hb->add_child(search); + + object_menu = memnew(MenuButton); + object_menu->set_shortcut_context(this); + object_menu->set_icon(get_theme_icon("Tools", "EditorIcons")); + property_tools_hb->add_child(object_menu); + object_menu->set_tooltip(TTR("Manage object properties.")); + object_menu->get_popup()->connect("id_pressed", callable_mp(this, &InspectorDock::_menu_option)); warning = memnew(Button); add_child(warning); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 6a3f8c679c..d50785d95c 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -81,9 +81,11 @@ class InspectorDock : public VBoxContainer { Button *resource_new_button; Button *resource_load_button; MenuButton *resource_save_button; + MenuButton *resource_extra_button; MenuButton *history_menu; LineEdit *search; + Button *open_docs_button; MenuButton *object_menu; EditorPath *editor_path; @@ -112,7 +114,7 @@ class InspectorDock : public VBoxContainer { void _prepare_history(); void _property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance); - void _transform_keyed(Object *sp, const String &p_sub, const Transform &p_key); + void _transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key); protected: static void _bind_methods(); diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index cc261ea868..9323c31fae 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -34,15 +34,14 @@ #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" #include "scene/3d/audio_stream_player_3d.h" -#include "scene/3d/baked_lightmap.h" #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" #include "scene/3d/decal.h" -#include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/gpu_particles_collision_3d.h" #include "scene/3d/light_3d.h" +#include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" #include "scene/3d/listener_3d.h" #include "scene/3d/mesh_instance_3d.h" @@ -57,6 +56,7 @@ #include "scene/3d/sprite_3d.h" #include "scene/3d/vehicle_body_3d.h" #include "scene/3d/visibility_notifier_3d.h" +#include "scene/3d/voxel_gi.h" #include "scene/resources/box_shape_3d.h" #include "scene/resources/capsule_shape_3d.h" #include "scene/resources/concave_polygon_shape_3d.h" @@ -455,7 +455,7 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector int vc = collision_segments.size(); const Vector3 *vptr = collision_segments.ptr(); - Transform t = spatial_node->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); bool any_out = false; for (int j = 0; j < fc; j++) { @@ -477,12 +477,12 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector } if (collision_mesh.is_valid()) { - Transform t = spatial_node->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); Vector3 mesh_scale = t.get_basis().get_scale(); t.orthonormalize(); - Transform it = t.affine_inverse(); + Transform3D it = t.affine_inverse(); Vector<Plane> transformed_frustum; @@ -508,7 +508,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, } if (r_gizmo_handle && !hidden) { - Transform t = spatial_node->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); if (billboard_handle) { t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1)); } @@ -560,7 +560,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, } if (selectable_icon_size > 0.0f) { - Transform t = spatial_node->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); Vector3 camera_position = p_camera->get_camera_transform().origin; if (camera_position.distance_squared_to(t.origin) > 0.01) { t.set_look_at(t.origin, camera_position); @@ -576,7 +576,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, Point2 center = p_camera->unproject_position(t.origin); - Transform orig_camera_transform = p_camera->get_camera_transform(); + Transform3D orig_camera_transform = p_camera->get_camera_transform(); if (orig_camera_transform.origin.distance_squared_to(t.origin) > 0.01 && ABS(orig_camera_transform.basis.get_axis(Vector3::AXIS_Z).dot(Vector3(0, 1, 0))) < 0.99) { @@ -609,7 +609,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, int vc = collision_segments.size(); const Vector3 *vptr = collision_segments.ptr(); - Transform t = spatial_node->get_global_transform(); + Transform3D t = spatial_node->get_global_transform(); if (billboard_handle) { t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1)); } @@ -657,13 +657,13 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, } if (collision_mesh.is_valid()) { - Transform gt = spatial_node->get_global_transform(); + Transform3D gt = spatial_node->get_global_transform(); if (billboard_handle) { gt.set_look_at(gt.origin, gt.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1)); } - Transform ai = gt.affine_inverse(); + Transform3D ai = gt.affine_inverse(); Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point)); Vector3 ray_dir = ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized(); Vector3 rpos, rnorm; @@ -826,7 +826,7 @@ Variant Light3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_i return Variant(); } -static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vector3 &p_to, float p_arc_radius, const Transform &p_arc_xform) { +static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vector3 &p_to, float p_arc_radius, const Transform3D &p_arc_xform) { //bleh, discrete is simpler static const int arc_test_points = 64; float min_d = 1e20; @@ -855,8 +855,8 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node()); - Transform gt = light->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = light->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -1084,8 +1084,8 @@ Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gi void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node()); - Transform gt = player->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = player->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -1230,8 +1230,8 @@ Variant Camera3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node()); - Transform gt = camera->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = camera->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -1239,7 +1239,7 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came Vector3 s[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) { - Transform gt2 = camera->get_global_transform(); + Transform3D gt2 = camera->get_global_transform(); float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], 1.0, gt2); camera->set("fov", CLAMP(a * 2.0, 1, 179)); } else { @@ -1418,7 +1418,7 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { lines.push_back(cam_pos); } - Transform local = camera->get_global_transform().affine_inverse(); + Transform3D local = camera->get_global_transform().affine_inverse(); for (int i = 0; i < lines.size(); i++) { lines.write[i] = local.xform(lines[i]); } @@ -1541,19 +1541,46 @@ Position3DGizmoPlugin::Position3DGizmoPlugin() { cursor_points = Vector<Vector3>(); Vector<Color> cursor_colors; - float cs = 0.25; + const float cs = 0.25; + // Add more points to create a "hard stop" in the color gradient. cursor_points.push_back(Vector3(+cs, 0, 0)); + cursor_points.push_back(Vector3()); + cursor_points.push_back(Vector3()); cursor_points.push_back(Vector3(-cs, 0, 0)); + cursor_points.push_back(Vector3(0, +cs, 0)); + cursor_points.push_back(Vector3()); + cursor_points.push_back(Vector3()); cursor_points.push_back(Vector3(0, -cs, 0)); + cursor_points.push_back(Vector3(0, 0, +cs)); + cursor_points.push_back(Vector3()); + cursor_points.push_back(Vector3()); cursor_points.push_back(Vector3(0, 0, -cs)); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_x_color", "Editor")); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_x_color", "Editor")); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_y_color", "Editor")); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_y_color", "Editor")); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_z_color", "Editor")); - cursor_colors.push_back(EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_z_color", "Editor")); + + // Use the axis color which is brighter for the positive axis. + // Use a darkened axis color for the negative axis. + // This makes it possible to see in which direction the Position3D node is rotated + // (which can be important depending on how it's used). + const Color color_x = EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_x_color", "Editor"); + cursor_colors.push_back(color_x); + cursor_colors.push_back(color_x); + // FIXME: Use less strong darkening factor once GH-48573 is fixed. + // The current darkening factor compensates for lines being too bright in the 3D editor. + cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75)); + cursor_colors.push_back(color_x.lerp(Color(0, 0, 0), 0.75)); + + const Color color_y = EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_y_color", "Editor"); + cursor_colors.push_back(color_y); + cursor_colors.push_back(color_y); + cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75)); + cursor_colors.push_back(color_y.lerp(Color(0, 0, 0), 0.75)); + + const Color color_z = EditorNode::get_singleton()->get_gui_base()->get_theme_color("axis_z_color", "Editor"); + cursor_colors.push_back(color_z); + cursor_colors.push_back(color_z); + cursor_colors.push_back(color_z.lerp(Color(0, 0, 0), 0.75)); + cursor_colors.push_back(color_z.lerp(Color(0, 0, 0), 0.75)); Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -1617,7 +1644,7 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { surface_tool->begin(Mesh::PRIMITIVE_LINES); surface_tool->set_material(material); - Vector<Transform> grests; + Vector<Transform3D> grests; grests.resize(skel->get_bone_count()); Vector<int> bones; @@ -1731,59 +1758,10 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { surface_tool->set_color(bonecolor); surface_tool->add_vertex(points[(j + 1) % 4]); } - - /* - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(0.4,1,0.4,0.4)); - surface_tool->add_vertex(v0); - bones[0]=i; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(0.4,1,0.4,0.4)); - surface_tool->add_vertex(v1); -*/ } else { grests.write[i] = skel->get_bone_rest(i); bones.write[0] = i; } - /* - Transform t = grests[i]; - t.orthonormalize(); - - for (int i=0;i<6;i++) { - - - Vector3 face_points[4]; - - for (int j=0;j<4;j++) { - float v[3]; - v[0]=1.0; - v[1]=1-2*((j>>1)&1); - v[2]=v[1]*(1-2*(j&1)); - - for (int k=0;k<3;k++) { - if (i<3) - face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); - else - face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); - } - } - - for(int j=0;j<4;j++) { - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); - surface_tool->add_vertex(t.xform(face_points[j]*0.04)); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); - surface_tool->add_vertex(t.xform(face_points[(j+1)%4]*0.04)); - } - - } - */ } Ref<ArrayMesh> m = surface_tool->commit(); @@ -2196,9 +2174,9 @@ Variant VisibilityNotifier3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_g void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { VisibilityNotifier3D *notifier = Object::cast_to<VisibilityNotifier3D>(p_gizmo->get_spatial_node()); - Transform gt = notifier->get_global_transform(); + Transform3D gt = notifier->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gi = gt.affine_inverse(); bool move = p_idx >= 3; p_idx = p_idx % 3; @@ -2388,8 +2366,8 @@ Variant GPUParticles3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node()); - Transform gt = particles->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = particles->get_global_transform(); + Transform3D gi = gt.affine_inverse(); bool move = p_idx >= 3; p_idx = p_idx % 3; @@ -2555,8 +2533,8 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(EditorNode3DGizmo * void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { Node3D *sn = p_gizmo->get_spatial_node(); - Transform gt = sn->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = sn->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -2814,9 +2792,9 @@ Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node()); - Transform gt = probe->get_global_transform(); + Transform3D gt = probe->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gi = gt.affine_inverse(); if (p_idx < 3) { Vector3 extents = probe->get_extents(); @@ -2993,9 +2971,9 @@ Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); - Transform gt = decal->get_global_transform(); + Transform3D gt = decal->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gi = gt.affine_inverse(); Vector3 extents = decal->get_extents(); @@ -3086,35 +3064,35 @@ void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } /////////////////////////////// -GIProbeGizmoPlugin::GIProbeGizmoPlugin() { - Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6)); +VoxelGIGizmoPlugin::VoxelGIGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/voxel_gi", Color(0.5, 1, 0.6)); - create_material("gi_probe_material", gizmo_color); + create_material("voxel_gi_material", gizmo_color); // This gizmo draws a lot of lines. Use a low opacity to make it not too intrusive. gizmo_color.a = 0.1; - create_material("gi_probe_internal_material", gizmo_color); + create_material("voxel_gi_internal_material", gizmo_color); gizmo_color.a = 0.05; - create_material("gi_probe_solid_material", gizmo_color); + create_material("voxel_gi_solid_material", gizmo_color); - create_icon_material("gi_probe_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoGIProbe", "EditorIcons")); + create_icon_material("voxel_gi_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoVoxelGI", "EditorIcons")); create_handle_material("handles"); } -bool GIProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) { - return Object::cast_to<GIProbe>(p_spatial) != nullptr; +bool VoxelGIGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<VoxelGI>(p_spatial) != nullptr; } -String GIProbeGizmoPlugin::get_gizmo_name() const { - return "GIProbe"; +String VoxelGIGizmoPlugin::get_gizmo_name() const { + return "VoxelGI"; } -int GIProbeGizmoPlugin::get_priority() const { +int VoxelGIGizmoPlugin::get_priority() const { return -1; } -String GIProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { switch (p_idx) { case 0: return "Extents X"; @@ -3127,16 +3105,16 @@ String GIProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int return ""; } -Variant GIProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { - GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node()); +Variant VoxelGIGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); return probe->get_extents(); } -void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { - GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node()); +void VoxelGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); - Transform gt = probe->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = probe->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 extents = probe->get_extents(); @@ -3163,8 +3141,8 @@ void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer probe->set_extents(extents); } -void GIProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { - GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node()); +void VoxelGIGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); Vector3 restore = p_restore; @@ -3180,19 +3158,19 @@ void GIProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, co ur->commit_action(); } -void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node()); +void VoxelGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node()); - Ref<Material> material = get_material("gi_probe_material", p_gizmo); - Ref<Material> icon = get_material("gi_probe_icon", p_gizmo); - Ref<Material> material_internal = get_material("gi_probe_internal_material", p_gizmo); + Ref<Material> material = get_material("voxel_gi_material", p_gizmo); + Ref<Material> icon = get_material("voxel_gi_icon", p_gizmo); + Ref<Material> material_internal = get_material("voxel_gi_internal_material", p_gizmo); p_gizmo->clear(); Vector<Vector3> lines; Vector3 extents = probe->get_extents(); - static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 }; + static const int subdivs[VoxelGI::SUBDIV_MAX] = { 64, 128, 256, 512 }; AABB aabb = AABB(-extents, extents * 2); int subdiv = subdivs[probe->get_subdiv()]; @@ -3256,7 +3234,7 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } if (p_gizmo->is_selected()) { - Ref<Material> solid_material = get_material("gi_probe_solid_material", p_gizmo); + Ref<Material> solid_material = get_material("voxel_gi_solid_material", p_gizmo); p_gizmo->add_solid_box(solid_material, aabb.get_size()); } @@ -3266,7 +3244,7 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { //// -BakedLightmapGizmoPlugin::BakedLightmapGizmoPlugin() { +LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/lightmap_lines", Color(0.5, 0.6, 1)); gizmo_color.a = 0.1; @@ -3280,39 +3258,39 @@ BakedLightmapGizmoPlugin::BakedLightmapGizmoPlugin() { add_material("lightmap_probe_material", mat); - create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoBakedLightmap", "EditorIcons")); + create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoLightmapGI", "EditorIcons")); } -String BakedLightmapGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { +String LightmapGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { return ""; } -Variant BakedLightmapGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { +Variant LightmapGIGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { return Variant(); } -void BakedLightmapGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { +void LightmapGIGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { } -void BakedLightmapGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { +void LightmapGIGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { } -bool BakedLightmapGizmoPlugin::has_gizmo(Node3D *p_spatial) { - return Object::cast_to<BakedLightmap>(p_spatial) != nullptr; +bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<LightmapGI>(p_spatial) != nullptr; } -String BakedLightmapGizmoPlugin::get_gizmo_name() const { - return "BakedLightmap"; +String LightmapGIGizmoPlugin::get_gizmo_name() const { + return "LightmapGI"; } -int BakedLightmapGizmoPlugin::get_priority() const { +int LightmapGIGizmoPlugin::get_priority() const { return -1; } -void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { +void LightmapGIGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo); - BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); - Ref<BakedLightmapData> data = baker->get_light_data(); + LightmapGI *baker = Object::cast_to<LightmapGI>(p_gizmo->get_spatial_node()); + Ref<LightmapGIData> data = baker->get_light_data(); p_gizmo->add_unscaled_billboard(icon, 0.05); @@ -3583,7 +3561,7 @@ void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { co->get_shape_owners(&owners); for (List<uint32_t>::Element *E = owners.front(); E; E = E->next()) { uint32_t owner_id = E->get(); - Transform xform = co->shape_owner_get_transform(owner_id); + Transform3D xform = co->shape_owner_get_transform(owner_id); Object *owner = co->shape_owner_get_owner(owner_id); // Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo. if (!Object::cast_to<CollisionShape3D>(owner) && !Object::cast_to<CollisionPolygon3D>(owner)) { @@ -3701,8 +3679,8 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i return; } - Transform gt = cs->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = cs->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -4369,7 +4347,7 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { #define BODY_A_RADIUS 0.25 #define BODY_B_RADIUS 0.27 -Basis JointGizmosDrawer::look_body(const Transform &p_joint_transform, const Transform &p_body_transform) { +Basis JointGizmosDrawer::look_body(const Transform3D &p_joint_transform, const Transform3D &p_body_transform) { const Vector3 &p_eye(p_joint_transform.origin); const Vector3 &p_target(p_body_transform.origin); @@ -4394,7 +4372,7 @@ Basis JointGizmosDrawer::look_body(const Transform &p_joint_transform, const Tra return base; } -Basis JointGizmosDrawer::look_body_toward(Vector3::Axis p_axis, const Transform &joint_transform, const Transform &body_transform) { +Basis JointGizmosDrawer::look_body_toward(Vector3::Axis p_axis, const Transform3D &joint_transform, const Transform3D &body_transform) { switch (p_axis) { case Vector3::AXIS_X: return look_body_toward_x(joint_transform, body_transform); @@ -4407,7 +4385,7 @@ Basis JointGizmosDrawer::look_body_toward(Vector3::Axis p_axis, const Transform } } -Basis JointGizmosDrawer::look_body_toward_x(const Transform &p_joint_transform, const Transform &p_body_transform) { +Basis JointGizmosDrawer::look_body_toward_x(const Transform3D &p_joint_transform, const Transform3D &p_body_transform) { const Vector3 &p_eye(p_joint_transform.origin); const Vector3 &p_target(p_body_transform.origin); @@ -4438,7 +4416,7 @@ Basis JointGizmosDrawer::look_body_toward_x(const Transform &p_joint_transform, return base; } -Basis JointGizmosDrawer::look_body_toward_y(const Transform &p_joint_transform, const Transform &p_body_transform) { +Basis JointGizmosDrawer::look_body_toward_y(const Transform3D &p_joint_transform, const Transform3D &p_body_transform) { const Vector3 &p_eye(p_joint_transform.origin); const Vector3 &p_target(p_body_transform.origin); @@ -4469,7 +4447,7 @@ Basis JointGizmosDrawer::look_body_toward_y(const Transform &p_joint_transform, return base; } -Basis JointGizmosDrawer::look_body_toward_z(const Transform &p_joint_transform, const Transform &p_body_transform) { +Basis JointGizmosDrawer::look_body_toward_z(const Transform3D &p_joint_transform, const Transform3D &p_body_transform) { const Vector3 &p_eye(p_joint_transform.origin); const Vector3 &p_target(p_body_transform.origin); @@ -4500,7 +4478,7 @@ Basis JointGizmosDrawer::look_body_toward_z(const Transform &p_joint_transform, return base; } -void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) { +void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform3D &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) { if (p_limit_lower == p_limit_upper) { r_points.push_back(p_offset.translated(Vector3()).origin); r_points.push_back(p_offset.translated(p_base.xform(Vector3(0.5, 0, 0))).origin); @@ -4562,7 +4540,7 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const } } -void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points) { +void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points) { float r = 1.0; float w = r * Math::sin(p_swing); float d = r * Math::cos(p_swing); @@ -4666,7 +4644,7 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> body_b_points; if (Object::cast_to<PinJoint3D>(joint)) { - CreatePinJointGizmo(Transform(), points); + CreatePinJointGizmo(Transform3D(), points); p_gizmo->add_collision_segments(points); p_gizmo->add_lines(points, common_material); } @@ -4674,10 +4652,10 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { HingeJoint3D *hinge = Object::cast_to<HingeJoint3D>(joint); if (hinge) { CreateHingeJointGizmo( - Transform(), + Transform3D(), hinge->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), + node_body_a ? node_body_a->get_global_transform() : Transform3D(), + node_body_b ? node_body_b->get_global_transform() : Transform3D(), hinge->get_param(HingeJoint3D::PARAM_LIMIT_LOWER), hinge->get_param(HingeJoint3D::PARAM_LIMIT_UPPER), hinge->get_flag(HingeJoint3D::FLAG_USE_LIMIT), @@ -4697,10 +4675,10 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { SliderJoint3D *slider = Object::cast_to<SliderJoint3D>(joint); if (slider) { CreateSliderJointGizmo( - Transform(), + Transform3D(), slider->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), + node_body_a ? node_body_a->get_global_transform() : Transform3D(), + node_body_b ? node_body_b->get_global_transform() : Transform3D(), slider->get_param(SliderJoint3D::PARAM_ANGULAR_LIMIT_LOWER), slider->get_param(SliderJoint3D::PARAM_ANGULAR_LIMIT_UPPER), slider->get_param(SliderJoint3D::PARAM_LINEAR_LIMIT_LOWER), @@ -4721,10 +4699,10 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { ConeTwistJoint3D *cone = Object::cast_to<ConeTwistJoint3D>(joint); if (cone) { CreateConeTwistJointGizmo( - Transform(), + Transform3D(), cone->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), + node_body_a ? node_body_a->get_global_transform() : Transform3D(), + node_body_b ? node_body_b->get_global_transform() : Transform3D(), cone->get_param(ConeTwistJoint3D::PARAM_SWING_SPAN), cone->get_param(ConeTwistJoint3D::PARAM_TWIST_SPAN), node_body_a ? &body_a_points : nullptr, @@ -4740,10 +4718,10 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Generic6DOFJoint3D *gen = Object::cast_to<Generic6DOFJoint3D>(joint); if (gen) { CreateGeneric6DOFJointGizmo( - Transform(), + Transform3D(), gen->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), + node_body_a ? node_body_a->get_global_transform() : Transform3D(), + node_body_b ? node_body_b->get_global_transform() : Transform3D(), gen->get_param_x(Generic6DOFJoint3D::PARAM_ANGULAR_LOWER_LIMIT), gen->get_param_x(Generic6DOFJoint3D::PARAM_ANGULAR_UPPER_LIMIT), @@ -4780,7 +4758,7 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } } -void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points) { +void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform3D &p_offset, Vector<Vector3> &r_cursor_points) { float cs = 0.25; r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin); @@ -4791,7 +4769,7 @@ void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector<V r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin); } -void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { +void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); @@ -4821,7 +4799,7 @@ void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const } } -void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { +void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { p_linear_limit_lower = -p_linear_limit_lower; p_linear_limit_upper = -p_linear_limit_upper; @@ -4880,7 +4858,7 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const } } -void Joint3DGizmoPlugin::CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { +void Joint3DGizmoPlugin::CreateConeTwistJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { if (r_body_a_points) { JointGizmosDrawer::draw_cone( p_offset, @@ -4901,10 +4879,10 @@ void Joint3DGizmoPlugin::CreateConeTwistJointGizmo(const Transform &p_offset, co } void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo( - const Transform &p_offset, - const Transform &p_trs_joint, - const Transform &p_trs_body_a, - const Transform &p_trs_body_b, + const Transform3D &p_offset, + const Transform3D &p_trs_joint, + const Transform3D &p_trs_body_a, + const Transform3D &p_trs_body_b, real_t p_angular_limit_lower_x, real_t p_angular_limit_upper_x, real_t p_linear_limit_lower_x, diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index 95344176ad..8a0e10241a 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -316,8 +316,8 @@ public: DecalGizmoPlugin(); }; -class GIProbeGizmoPlugin : public EditorNode3DGizmoPlugin { - GDCLASS(GIProbeGizmoPlugin, EditorNode3DGizmoPlugin); +class VoxelGIGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(VoxelGIGizmoPlugin, EditorNode3DGizmoPlugin); public: bool has_gizmo(Node3D *p_spatial) override; @@ -330,11 +330,11 @@ public: void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; - GIProbeGizmoPlugin(); + VoxelGIGizmoPlugin(); }; -class BakedLightmapGizmoPlugin : public EditorNode3DGizmoPlugin { - GDCLASS(BakedLightmapGizmoPlugin, EditorNode3DGizmoPlugin); +class LightmapGIGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(LightmapGIGizmoPlugin, EditorNode3DGizmoPlugin); public: bool has_gizmo(Node3D *p_spatial) override; @@ -347,7 +347,7 @@ public: void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override; void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override; - BakedLightmapGizmoPlugin(); + LightmapGIGizmoPlugin(); }; class LightmapProbeGizmoPlugin : public EditorNode3DGizmoPlugin { @@ -428,17 +428,17 @@ public: class JointGizmosDrawer { public: - static Basis look_body(const Transform &p_joint_transform, const Transform &p_body_transform); - static Basis look_body_toward(Vector3::Axis p_axis, const Transform &joint_transform, const Transform &body_transform); - static Basis look_body_toward_x(const Transform &p_joint_transform, const Transform &p_body_transform); - static Basis look_body_toward_y(const Transform &p_joint_transform, const Transform &p_body_transform); + static Basis look_body(const Transform3D &p_joint_transform, const Transform3D &p_body_transform); + static Basis look_body_toward(Vector3::Axis p_axis, const Transform3D &joint_transform, const Transform3D &body_transform); + static Basis look_body_toward_x(const Transform3D &p_joint_transform, const Transform3D &p_body_transform); + static Basis look_body_toward_y(const Transform3D &p_joint_transform, const Transform3D &p_body_transform); /// Special function just used for physics joints, it returns a basis constrained toward Joint Z axis /// with axis X and Y that are looking toward the body and oriented toward up - static Basis look_body_toward_z(const Transform &p_joint_transform, const Transform &p_body_transform); + static Basis look_body_toward_z(const Transform3D &p_joint_transform, const Transform3D &p_body_transform); // Draw circle around p_axis - static void draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse = false); - static void draw_cone(const Transform &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points); + static void draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform3D &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse = false); + static void draw_cone(const Transform3D &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points); }; class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin { @@ -455,15 +455,15 @@ public: int get_priority() const override; void redraw(EditorNode3DGizmo *p_gizmo) override; - static void CreatePinJointGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points); - static void CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); - static void CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); - static void CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); + static void CreatePinJointGizmo(const Transform3D &p_offset, Vector<Vector3> &r_cursor_points); + static void CreateHingeJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); + static void CreateSliderJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); + static void CreateConeTwistJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points); static void CreateGeneric6DOFJointGizmo( - const Transform &p_offset, - const Transform &p_trs_joint, - const Transform &p_trs_body_a, - const Transform &p_trs_body_b, + const Transform3D &p_offset, + const Transform3D &p_trs_joint, + const Transform3D &p_trs_body_a, + const Transform3D &p_trs_body_b, real_t p_angular_limit_lower_x, real_t p_angular_limit_upper_x, real_t p_linear_limit_lower_x, diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 2be586733b..0083876e69 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -666,93 +666,6 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel } } -void CanvasItemEditor::_get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items) { - Point2 screen_pos = transform.xform(p_pos); - - for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { - Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from)); - - Vector<Vector2> bone_shape; - if (!_get_bone_shape(&bone_shape, nullptr, E)) { - continue; - } - - // Check if the point is inside the Polygon2D - if (Geometry2D::is_point_in_polygon(screen_pos, bone_shape)) { - // Check if the item is already in the list - bool duplicate = false; - for (int i = 0; i < r_items.size(); i++) { - if (r_items[i].item == from_node) { - duplicate = true; - break; - } - } - if (duplicate) { - continue; - } - - // Else, add it - _SelectResult res; - res.item = from_node; - res.z_index = from_node ? from_node->get_z_index() : 0; - res.has_z = from_node; - r_items.push_back(res); - } - } -} - -bool CanvasItemEditor::_get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> *outline_shape, Map<BoneKey, BoneList>::Element *bone) { - int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); - int bone_outline_width = EditorSettings::get_singleton()->get("editors/2d/bone_outline_size"); - - Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(bone->key().from)); - Node2D *to_node = Object::cast_to<Node2D>(ObjectDB::get_instance(bone->key().to)); - - if (!from_node) { - return false; - } - if (!from_node->is_inside_tree()) { - return false; //may have been removed - } - - if (!to_node && bone->get().length == 0) { - return false; - } - - Vector2 from = transform.xform(from_node->get_global_position()); - Vector2 to; - - if (to_node) { - to = transform.xform(to_node->get_global_position()); - } else { - to = transform.xform(from_node->get_global_transform().xform(Vector2(bone->get().length, 0))); - } - - Vector2 rel = to - from; - Vector2 relt = rel.orthogonal().normalized() * bone_width; - Vector2 reln = rel.normalized(); - Vector2 reltn = relt.normalized(); - - if (shape) { - shape->clear(); - shape->push_back(from); - shape->push_back(from + rel * 0.2 + relt); - shape->push_back(to); - shape->push_back(from + rel * 0.2 - relt); - } - - if (outline_shape) { - outline_shape->clear(); - outline_shape->push_back(from + (-reln - reltn) * bone_outline_width); - outline_shape->push_back(from + (-reln + reltn) * bone_outline_width); - outline_shape->push_back(from + rel * 0.2 + relt + reltn * bone_outline_width); - outline_shape->push_back(to + (reln + reltn) * bone_outline_width); - outline_shape->push_back(to + (reln - reltn) * bone_outline_width); - outline_shape->push_back(from + rel * 0.2 - relt - reltn * bone_outline_width); - } - return true; -} - void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { if (!p_node) { return; @@ -886,50 +799,6 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 return output; } -void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state) { - if (p_bones_length) { - *p_bones_length = List<float>(); - } - if (p_bones_state) { - *p_bones_state = List<Dictionary>(); - } - - const Node2D *bone = Object::cast_to<Node2D>(p_canvas_item); - if (bone && bone->has_meta("_edit_bone_")) { - // Check if we have an IK chain - List<const Node2D *> bone_ik_list; - bool ik_found = false; - bone = Object::cast_to<Node2D>(bone->get_parent()); - while (bone) { - bone_ik_list.push_back(bone); - if (bone->has_meta("_edit_ik_")) { - ik_found = true; - break; - } else if (!bone->has_meta("_edit_bone_")) { - break; - } - bone = Object::cast_to<Node2D>(bone->get_parent()); - } - - //Save the bone state and length if we have an IK chain - if (ik_found) { - bone = Object::cast_to<Node2D>(p_canvas_item); - Transform2D bone_xform = bone->get_global_transform(); - for (List<const Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) { - bone_xform = bone_xform * bone->get_transform().affine_inverse(); - const Node2D *parent_bone = bone_E->get(); - if (p_bones_length) { - p_bones_length->push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position())); - } - if (p_bones_state) { - p_bones_state->push_back(parent_bone->_edit_get_state()); - } - bone = parent_bone; - } - } - } -} - void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) { for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); @@ -942,31 +811,15 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items } else { se->pre_drag_rect = Rect2(); } - - // If we have a bone, save the state of all nodes in the IK chain - _save_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_length), &(se->pre_drag_bones_undo_state)); } } } -void CanvasItemEditor::_restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state) { - CanvasItem *canvas_item = p_canvas_item; - for (const List<Dictionary>::Element *E = p_bones_state->front(); E; E = E->next()) { - canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent()); - canvas_item->_edit_set_state(E->get()); - } -} - void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones) { for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (se) { - canvas_item->_edit_set_state(se->undo_state); - if (restore_bones) { - _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state)); - } - } + canvas_item->_edit_set_state(se->undo_state); } } @@ -1497,76 +1350,6 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { return false; } -void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) { - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(leaf_node); - if (se) { - int nb_bones = se->pre_drag_bones_undo_state.size(); - if (nb_bones > 0) { - // Build the node list - Point2 leaf_pos = target_position; - - List<Node2D *> joints_list; - List<Point2> joints_pos; - Node2D *joint = leaf_node; - Transform2D joint_transform = leaf_node->get_global_transform_with_canvas(); - for (int i = 0; i < nb_bones + 1; i++) { - joints_list.push_back(joint); - joints_pos.push_back(joint_transform.get_origin()); - joint_transform = joint_transform * joint->get_transform().affine_inverse(); - joint = Object::cast_to<Node2D>(joint->get_parent()); - } - Point2 root_pos = joints_list.back()->get()->get_global_transform_with_canvas().get_origin(); - - // Restraints the node to a maximum distance is necessary - float total_len = 0; - for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) { - total_len += E->get(); - } - if ((root_pos.distance_to(leaf_pos)) > total_len) { - Vector2 rel = leaf_pos - root_pos; - rel = rel.normalized() * total_len; - leaf_pos = root_pos + rel; - } - joints_pos[0] = leaf_pos; - - // Run the solver - int solver_iterations = 64; - float solver_k = 0.3; - - // Build the position list - for (int i = 0; i < solver_iterations; i++) { - // Handle the leaf joint - int node_id = 0; - for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) { - Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized(); - int len = E->get(); - if (E == se->pre_drag_bones_length.front()) { - joints_pos[1] = joints_pos[1].lerp(joints_pos[0] + len * direction, solver_k); - } else if (E == se->pre_drag_bones_length.back()) { - joints_pos[node_id] = joints_pos[node_id].lerp(joints_pos[node_id + 1] - len * direction, solver_k); - } else { - Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0; - joints_pos[node_id] = joints_pos[node_id].lerp(center - (direction * len) / 2.0, solver_k); - joints_pos[node_id + 1] = joints_pos[node_id + 1].lerp(center + (direction * len) / 2.0, solver_k); - } - node_id++; - } - } - - // Set the position - for (int node_id = joints_list.size() - 1; node_id > 0; node_id--) { - Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized(); - Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized(); - float rot = current.angle_to(target); - if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) { - rot = -rot; - } - joints_list[node_id]->rotate(rot); - } - } - } -} - bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; @@ -2208,14 +1991,6 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_MOVE || drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y) { // Move the nodes if (m.is_valid()) { - // Save the ik chain for reapplying before IK solve - Vector<List<Dictionary>> all_bones_ik_states; - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - List<Dictionary> bones_ik_states; - _save_canvas_item_ik_chain(E->get(), nullptr, &bones_ik_states); - all_bones_ik_states.push_back(bones_ik_states); - } - _restore_canvas_item_state(drag_selection, true); drag_to = transform.affine_inverse().xform(m->get_position()); @@ -2244,25 +2019,12 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } } - bool force_no_IK = m->is_alt_pressed(); int index = 0; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (se) { - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - Node2D *node2d = Object::cast_to<Node2D>(canvas_item); - if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) { - real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); - real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); - _solve_IK(node2d, new_pos); - } else { - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); - } - } + Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); + + canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); index++; } return true; @@ -2325,14 +2087,6 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } if (drag_selection.size() > 0) { - // Save the ik chain for reapplying before IK solve - Vector<List<Dictionary>> all_bones_ik_states; - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - List<Dictionary> bones_ik_states; - _save_canvas_item_ik_chain(E->get(), nullptr, &bones_ik_states); - all_bones_ik_states.push_back(bones_ik_states); - } - _restore_canvas_item_state(drag_selection, true); bool move_local_base = k->is_alt_pressed(); @@ -2384,21 +2138,9 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { int index = 0; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (se) { - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - - Node2D *node2d = Object::cast_to<Node2D>(canvas_item); - if (node2d && se->pre_drag_bones_undo_state.size() > 0) { - real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index])); - real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation(); - node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation); - _solve_IK(node2d, new_pos); - } else { - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); - } - } + Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); + + canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); index++; } } @@ -2524,18 +2266,12 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Find the item to select CanvasItem *canvas_item = nullptr; - // Retrieve the bones Vector<_SelectResult> selection = Vector<_SelectResult>(); - _get_bones_at_pos(click, selection); + // Retrieve the canvas items + selection = Vector<_SelectResult>(); + _get_canvas_items_at_pos(click, selection); if (!selection.is_empty()) { canvas_item = selection[0].item; - } else { - // Retrieve the canvas items - selection = Vector<_SelectResult>(); - _get_canvas_items_at_pos(click, selection); - if (!selection.is_empty()) { - canvas_item = selection[0].item; - } } if (!canvas_item) { @@ -3734,65 +3470,6 @@ void CanvasItemEditor::_draw_axis() { } } -void CanvasItemEditor::_draw_bones() { - RID ci = viewport->get_canvas_item(); - - if (skeleton_show_bones) { - Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); - Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2"); - Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); - Color bone_outline_color = EditorSettings::get_singleton()->get("editors/2d/bone_outline_color"); - Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); - - for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { - Vector<Vector2> bone_shape; - Vector<Vector2> bone_shape_outline; - if (!_get_bone_shape(&bone_shape, &bone_shape_outline, E)) { - continue; - } - - Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from)); - if (!from_node->is_visible_in_tree()) { - continue; - } - - Vector<Color> colors; - if (from_node->has_meta("_edit_ik_")) { - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - } else { - colors.push_back(bone_color1); - colors.push_back(bone_color2); - colors.push_back(bone_color1); - colors.push_back(bone_color2); - } - - Vector<Color> outline_colors; - - if (editor_selection->is_selected(from_node)) { - outline_colors.push_back(bone_selected_color); - outline_colors.push_back(bone_selected_color); - outline_colors.push_back(bone_selected_color); - outline_colors.push_back(bone_selected_color); - outline_colors.push_back(bone_selected_color); - outline_colors.push_back(bone_selected_color); - } else { - outline_colors.push_back(bone_outline_color); - outline_colors.push_back(bone_outline_color); - outline_colors.push_back(bone_outline_color); - outline_colors.push_back(bone_outline_color); - outline_colors.push_back(bone_outline_color); - outline_colors.push_back(bone_outline_color); - } - - RenderingServer::get_singleton()->canvas_item_add_polygon(ci, bone_shape_outline, outline_colors); - RenderingServer::get_singleton()->canvas_item_add_primitive(ci, bone_shape, colors, Vector<Vector2>(), RID()); - } - } -} - void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { ERR_FAIL_COND(!p_node); @@ -3908,72 +3585,6 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p } } -bool CanvasItemEditor::_build_bones_list(Node *p_node) { - ERR_FAIL_COND_V(!p_node, false); - - bool has_child_bones = false; - - for (int i = 0; i < p_node->get_child_count(); i++) { - if (_build_bones_list(p_node->get_child(i))) { - has_child_bones = true; - } - } - - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - Node *scene = editor->get_edited_scene(); - if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && canvas_item != scene->get_deepest_editable_node(canvas_item))) { - return false; - } - - Node *parent = canvas_item->get_parent(); - - if (Object::cast_to<Bone2D>(canvas_item)) { - if (Object::cast_to<Bone2D>(parent)) { - // Add as bone->parent relationship - BoneKey bk; - bk.from = parent->get_instance_id(); - bk.to = canvas_item->get_instance_id(); - if (!bone_list.has(bk)) { - BoneList b; - b.length = 0; - bone_list[bk] = b; - } - - bone_list[bk].last_pass = bone_last_frame; - } - - if (!has_child_bones) { - // Add a last bone if the Bone2D has no Bone2D child - BoneKey bk; - bk.from = canvas_item->get_instance_id(); - bk.to = ObjectID(); - if (!bone_list.has(bk)) { - BoneList b; - b.length = 0; - bone_list[bk] = b; - } - bone_list[bk].last_pass = bone_last_frame; - } - - return true; - } - - if (canvas_item->has_meta("_edit_bone_")) { - // Add a "custom bone" - BoneKey bk; - bk.from = parent->get_instance_id(); - bk.to = canvas_item->get_instance_id(); - if (!bone_list.has(bk)) { - BoneList b; - b.length = 0; - bone_list[bk] = b; - } - bone_list[bk].last_pass = bone_last_frame; - } - - return false; -} - void CanvasItemEditor::_draw_viewport() { // Update the transform transform = Transform2D(); @@ -4033,7 +3644,6 @@ void CanvasItemEditor::_draw_viewport() { force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport); } - _draw_bones(); if (show_rulers) { _draw_rulers(); } @@ -4159,8 +3769,8 @@ void CanvasItemEditor::_notification(int p_what) { } Bone2D *bone = Object::cast_to<Bone2D>(b); - if (bone && bone->get_default_length() != E->get().length) { - E->get().length = bone->get_default_length(); + if (bone && bone->get_length() != E->get().length) { + E->get().length = bone->get_length(); viewport->update(); } } @@ -4175,18 +3785,11 @@ void CanvasItemEditor::_notification(int p_what) { AnimationPlayerEditor::singleton->get_track_editor()->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_keying_changed)); _keying_changed(); - get_tree()->connect("node_added", callable_mp(this, &CanvasItemEditor::_tree_changed), varray()); - get_tree()->connect("node_removed", callable_mp(this, &CanvasItemEditor::_tree_changed), varray()); } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { select_sb->set_texture(get_theme_icon("EditorRect2D", "EditorIcons")); } - if (p_what == NOTIFICATION_EXIT_TREE) { - get_tree()->disconnect("node_added", callable_mp(this, &CanvasItemEditor::_tree_changed)); - get_tree()->disconnect("node_removed", callable_mp(this, &CanvasItemEditor::_tree_changed)); - } - if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { select_button->set_icon(get_theme_icon("ToolSelect", "EditorIcons")); list_select_button->set_icon(get_theme_icon("ListSelect", "EditorIcons")); @@ -4321,46 +3924,6 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { } } -void CanvasItemEditor::_queue_update_bone_list() { - if (bone_list_dirty) { - return; - } - - call_deferred("_update_bone_list"); - bone_list_dirty = true; -} - -void CanvasItemEditor::_update_bone_list() { - bone_last_frame++; - - if (editor->get_edited_scene()) { - _build_bones_list(editor->get_edited_scene()); - } - - List<Map<BoneKey, BoneList>::Element *> bone_to_erase; - for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { - if (E->get().last_pass != bone_last_frame) { - bone_to_erase.push_back(E); - continue; - } - - Node *node = Object::cast_to<Node>(ObjectDB::get_instance(E->key().from)); - if (!node || !node->is_inside_tree() || (node != get_tree()->get_edited_scene_root() && !get_tree()->get_edited_scene_root()->is_a_parent_of(node))) { - bone_to_erase.push_back(E); - continue; - } - } - while (bone_to_erase.size()) { - bone_list.erase(bone_to_erase.front()->get()); - bone_to_erase.pop_front(); - } - bone_list_dirty = false; -} - -void CanvasItemEditor::_tree_changed(Node *) { - _queue_update_bone_list(); -} - void CanvasItemEditor::_update_scrollbars() { updating_scroll = true; @@ -4376,8 +3939,6 @@ void CanvasItemEditor::_update_scrollbars() { Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); - _queue_update_bone_list(); - // Calculate scrollable area. Rect2 canvas_item_rect = Rect2(Point2(), screen_rect); if (editor->is_inside_tree() && editor->get_edited_scene()) { @@ -4837,10 +4398,19 @@ void CanvasItemEditor::_popup_callback(int p_op) { snap_dialog->popup_centered(Size2(220, 160) * EDSCALE); } break; case SKELETON_SHOW_BONES: { - skeleton_show_bones = !skeleton_show_bones; - int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones); - viewport->update(); + List<Node *> selection = editor_selection->get_selected_node_list(); + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + // Add children nodes so they are processed + for (int child = 0; child < E->get()->get_child_count(); child++) { + selection.push_back(E->get()->get_child(child)); + } + + Bone2D *bone_2d = Object::cast_to<Bone2D>(E->get()); + if (!bone_2d || !bone_2d->is_inside_tree()) { + continue; + } + bone_2d->_editor_set_show_bone_gizmo(!bone_2d->_editor_get_show_bone_gizmo()); + } } break; case SHOW_HELPERS: { show_helpers = !show_helpers; @@ -5189,107 +4759,45 @@ void CanvasItemEditor::_popup_callback(int p_op) { } break; case SKELETON_MAKE_BONES: { Map<Node *, Object *> &selection = editor_selection->get_selection(); + Node *editor_root = EditorNode::get_singleton()->get_edited_scene()->get_tree()->get_edited_scene_root(); - undo_redo->create_action(TTR("Create Custom Bone(s) from Node(s)")); + undo_redo->create_action(TTR("Create Custom Bone2D(s) from Node(s)")); for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { Node2D *n2d = Object::cast_to<Node2D>(E->key()); - if (!n2d) { - continue; - } - if (!n2d->is_visible_in_tree()) { - continue; - } - if (!n2d->get_parent_item()) { - continue; - } - if (n2d->has_meta("_edit_bone_") && n2d->get_meta("_edit_bone_")) { - continue; - } - - undo_redo->add_do_method(n2d, "set_meta", "_edit_bone_", true); - undo_redo->add_undo_method(n2d, "remove_meta", "_edit_bone_"); - } - undo_redo->add_do_method(this, "_queue_update_bone_list"); - undo_redo->add_undo_method(this, "_queue_update_bone_list"); - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); - undo_redo->commit_action(); - } break; - case SKELETON_CLEAR_BONES: { - Map<Node *, Object *> &selection = editor_selection->get_selection(); + Bone2D *new_bone = memnew(Bone2D); + String new_bone_name = n2d->get_name(); + new_bone_name += "Bone2D"; + new_bone->set_name(new_bone_name); + new_bone->set_transform(n2d->get_transform()); - undo_redo->create_action(TTR("Clear Bones")); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - Node2D *n2d = Object::cast_to<Node2D>(E->key()); - if (!n2d) { + Node *n2d_parent = n2d->get_parent(); + if (!n2d_parent) { continue; } - if (!n2d->is_visible_in_tree()) { - continue; - } - if (!n2d->has_meta("_edit_bone_")) { - continue; - } - - undo_redo->add_do_method(n2d, "remove_meta", "_edit_bone_"); - undo_redo->add_undo_method(n2d, "set_meta", "_edit_bone_", n2d->get_meta("_edit_bone_")); - } - undo_redo->add_do_method(this, "_queue_update_bone_list"); - undo_redo->add_undo_method(this, "_queue_update_bone_list"); - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); - undo_redo->commit_action(); - } break; - case SKELETON_SET_IK_CHAIN: { - List<Node *> selection = editor_selection->get_selected_node_list(); - - undo_redo->create_action(TTR("Make IK Chain")); - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); - if (!canvas_item || !canvas_item->is_visible_in_tree()) { - continue; - } - if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) { - continue; - } - if (canvas_item->has_meta("_edit_ik_") && canvas_item->get_meta("_edit_ik_")) { - continue; - } + undo_redo->add_do_method(n2d_parent, "add_child", new_bone); + undo_redo->add_do_method(n2d_parent, "remove_child", n2d); + undo_redo->add_do_method(new_bone, "add_child", n2d); + undo_redo->add_do_method(n2d, "set_transform", Transform2D()); + undo_redo->add_do_method(this, "_set_owner_for_node_and_children", new_bone, editor_root); - undo_redo->add_do_method(canvas_item, "set_meta", "_edit_ik_", true); - undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_ik_"); + undo_redo->add_undo_method(new_bone, "remove_child", n2d); + undo_redo->add_undo_method(n2d_parent, "add_child", n2d); + undo_redo->add_undo_method(n2d, "set_transform", new_bone->get_transform()); + undo_redo->add_undo_method(new_bone, "queue_free"); + undo_redo->add_undo_method(this, "_set_owner_for_node_and_children", n2d, editor_root); } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); } break; - case SKELETON_CLEAR_IK_CHAIN: { - Map<Node *, Object *> &selection = editor_selection->get_selection(); - - undo_redo->create_action(TTR("Clear IK Chain")); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *n2d = Object::cast_to<CanvasItem>(E->key()); - if (!n2d) { - continue; - } - if (!n2d->is_visible_in_tree()) { - continue; - } - if (!n2d->has_meta("_edit_ik_")) { - continue; - } - - undo_redo->add_do_method(n2d, "remove_meta", "_edit_ik_"); - undo_redo->add_undo_method(n2d, "set_meta", "_edit_ik_", n2d->get_meta("_edit_ik_")); - } - undo_redo->add_do_method(viewport, "update"); - undo_redo->add_undo_method(viewport, "update"); - undo_redo->commit_action(); + } +} - } break; +void CanvasItemEditor::_set_owner_for_node_and_children(Node *p_node, Node *p_owner) { + p_node->set_owner(p_owner); + for (int i = 0; i < p_node->get_child_count(); i++) { + _set_owner_for_node_and_children(p_node->get_child(i), p_owner); } } @@ -5358,14 +4866,12 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button); ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data); ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input); - ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list); - ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list); - ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position); - ClassDB::bind_method(D_METHOD("get_state"), &CanvasItemEditor::get_state); ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state); ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); ClassDB::bind_method(D_METHOD("_zoom_on_position"), &CanvasItemEditor::_zoom_on_position); + ClassDB::bind_method("_set_owner_for_node_and_children", &CanvasItemEditor::_set_owner_for_node_and_children); + ADD_SIGNAL(MethodInfo("item_lock_status_changed")); ADD_SIGNAL(MethodInfo("item_group_status_changed")); } @@ -5402,7 +4908,6 @@ Dictionary CanvasItemEditor::get_state() const { state["snap_scale"] = snap_scale; state["snap_relative"] = snap_relative; state["snap_pixel"] = snap_pixel; - state["skeleton_show_bones"] = skeleton_show_bones; return state; } @@ -5570,12 +5075,6 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel); } - if (state.has("skeleton_show_bones")) { - skeleton_show_bones = state["skeleton_show_bones"]; - int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones); - } - if (update_scrollbars) { _update_scrollbars(); } @@ -5658,8 +5157,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { selected_from_canvas = false; anchors_mode = false; - skeleton_show_bones = true; - drag_type = DRAG_NONE; drag_from = Vector2(); drag_to = Vector2(); @@ -5675,7 +5172,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { bone_last_frame = 0; - bone_list_dirty = false; tool = TOOL_SELECT; undo_redo = p_editor->get_undo_redo(); editor = p_editor; @@ -5940,13 +5436,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p = skeleton_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); p->add_separator(); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Custom Bone(s) from Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Custom Bones")), SKELETON_CLEAR_BONES); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bone2D Node(s) from Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); p->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback)); hb->add_child(memnew(VSeparator)); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 21ef3f88df..96a29e0c74 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -187,10 +187,7 @@ private: VIEW_FRAME_TO_SELECTION, PREVIEW_CANVAS_SCALE, SKELETON_MAKE_BONES, - SKELETON_CLEAR_BONES, - SKELETON_SHOW_BONES, - SKELETON_SET_IK_CHAIN, - SKELETON_CLEAR_IK_CHAIN + SKELETON_SHOW_BONES }; enum DragType { @@ -223,7 +220,6 @@ private: DRAG_KEY_MOVE }; - EditorSelection *editor_selection; bool selection_menu_additive_selection; Tool tool; @@ -277,7 +273,6 @@ private: bool snap_scale; bool snap_relative; bool snap_pixel; - bool skeleton_show_bones; bool key_pos; bool key_rot; bool key_scale; @@ -412,7 +407,6 @@ private: bool _is_node_movable(const Node *p_node, bool p_popup_warning = false); void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); void _get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, bool p_allow_locked = false); - void _get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items); void _find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); bool _select_click_on_item(CanvasItem *item, Point2 p_click_pos, bool p_append); @@ -423,9 +417,7 @@ private: void _add_canvas_item(CanvasItem *p_canvas_item); - void _save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state); void _save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones = false); - void _restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state); void _restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones = false); void _commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones = false); @@ -445,8 +437,6 @@ private: void _reset_create_position(); UndoRedo *undo_redo; - bool _build_bones_list(Node *p_node); - bool _get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> *outline_shape, Map<BoneKey, BoneList>::Element *bone); List<CanvasItem *> _get_edited_canvas_items(bool retreive_locked = false, bool remove_canvas_item_if_parent_in_selection = true); Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list); @@ -476,7 +466,6 @@ private: void _draw_control_helpers(Control *control); void _draw_selection(); void _draw_axis(); - void _draw_bones(); void _draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); void _draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); void _draw_hover(); @@ -503,8 +492,6 @@ private: void _focus_selection(int p_op); - void _solve_IK(Node2D *leaf_node, Point2 target_position); - SnapTarget snap_target[2]; Transform2D snap_transform; void _snap_if_closer_float( @@ -546,14 +533,11 @@ private: HSplitContainer *palette_split; VSplitContainer *bottom_split; - bool bone_list_dirty; - void _queue_update_bone_list(); - void _update_bone_list(); - void _tree_changed(Node *); - void _popup_warning_temporarily(Control *p_control, const float p_duration); void _popup_warning_depop(Control *p_control); + void _set_owner_for_node_and_children(Node *p_node, Node *p_owner); + friend class CanvasItemEditorPlugin; protected: @@ -641,6 +625,8 @@ public: bool is_anchors_mode_enabled() { return anchors_mode; }; + EditorSelection *editor_selection; + CanvasItemEditor(EditorNode *p_editor); }; diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index 252e5c68a0..6e71133c4f 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -108,8 +108,8 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con return false; } - Transform gt = node->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = node->get_global_transform(); + Transform3D gi = gt.affine_inverse(); float depth = _get_depth() * 0.5; Vector3 n = gt.basis.get_axis(2).normalized(); Plane p(gt.origin + n * depth, n); @@ -516,7 +516,7 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) { mode = MODE_EDIT; wip_active = false; imgeom = memnew(ImmediateGeometry3D); - imgeom->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001))); + imgeom->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -539,7 +539,7 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) { imgeom->add_child(pointsm); m.instance(); pointsm->set_mesh(m); - pointsm->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001))); + pointsm->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); snap_ignore = false; } diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 2d79e4f3e3..235ccb18cb 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -359,12 +359,12 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { camera = RS::get_singleton()->camera_create(); RS::get_singleton()->viewport_attach_camera(viewport, camera); - RS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3))); + RS::get_singleton()->camera_set_transform(camera, Transform3D(Basis(), Vector3(0, 0, 3))); RS::get_singleton()->camera_set_perspective(camera, 45, 0.1, 10); light = RS::get_singleton()->directional_light_create(); light_instance = RS::get_singleton()->instance_create2(light, scenario); - RS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); + RS::get_singleton()->instance_set_transform(light_instance, Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); light2 = RS::get_singleton()->directional_light_create(); RS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7)); @@ -372,7 +372,7 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { light_instance2 = RS::get_singleton()->instance_create2(light2, scenario); - RS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); + RS::get_singleton()->instance_set_transform(light_instance2, Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); sphere = RS::get_singleton()->mesh_create(); sphere_instance = RS::get_singleton()->instance_create2(sphere, scenario); @@ -720,7 +720,7 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 AABB aabb = mesh->get_aabb(); Vector3 ofs = aabb.position + aabb.size * 0.5; aabb.position -= ofs; - Transform xform; + Transform3D xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.125); xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.125) * xform.basis; AABB rot_aabb = xform.xform(aabb); @@ -780,20 +780,20 @@ EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() { camera = RS::get_singleton()->camera_create(); RS::get_singleton()->viewport_attach_camera(viewport, camera); - RS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3))); + RS::get_singleton()->camera_set_transform(camera, Transform3D(Basis(), Vector3(0, 0, 3))); //RS::get_singleton()->camera_set_perspective(camera,45,0.1,10); RS::get_singleton()->camera_set_orthogonal(camera, 1.0, 0.01, 1000.0); light = RS::get_singleton()->directional_light_create(); light_instance = RS::get_singleton()->instance_create2(light, scenario); - RS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); + RS::get_singleton()->instance_set_transform(light_instance, Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); light2 = RS::get_singleton()->directional_light_create(); RS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7)); //RS::get_singleton()->light_set_color(light2, RS::LIGHT_COLOR_SPECULAR, Color(0.0, 0.0, 0.0)); light_instance2 = RS::get_singleton()->instance_create2(light2, scenario); - RS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); + RS::get_singleton()->instance_set_transform(light_instance2, Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); //sphere = RS::get_singleton()->mesh_create(); mesh_instance = RS::get_singleton()->instance_create(); @@ -832,7 +832,7 @@ struct FSample { }; static FSample _samples[] = { - { "hani", U"漢語" }, + { "hani", U"漢字" }, { "armn", U"Աբ" }, { "copt", U"Αα" }, { "cyrl", U"Аб" }, diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp index fa58eb5480..8de7dc2447 100644 --- a/editor/plugins/font_editor_plugin.cpp +++ b/editor/plugins/font_editor_plugin.cpp @@ -56,7 +56,7 @@ struct FSample { }; static FSample _samples[] = { - { "hani", U"漢語" }, + { "hani", U"漢字" }, { "armn", U"Աբ" }, { "copt", U"Αα" }, { "cyrl", U"Аб" }, diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 89d6aaa5f9..17c7397729 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -177,7 +177,7 @@ void GPUParticles3DEditorBase::_node_selected(const NodePath &p_path) { return; } - Transform geom_xform = base_node->get_global_transform().affine_inverse() * vi->get_global_transform(); + Transform3D geom_xform = base_node->get_global_transform().affine_inverse() * vi->get_global_transform(); int gc = geometry.size(); Face3 *w = geometry.ptrw(); diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp index 470b61bf40..484fdabfe1 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/lightmap_gi_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* baked_lightmap_editor_plugin.cpp */ +/* lightmap_gi_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "baked_lightmap_editor_plugin.h" +#include "lightmap_gi_editor_plugin.h" -void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) { +void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) { if (lightmap) { - BakedLightmap::BakeError err; + LightmapGI::BakeError err; if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) { err = lightmap->bake(lightmap, p_file, bake_func_step); } else { @@ -42,7 +42,7 @@ void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) { bake_func_end(); switch (err) { - case BakedLightmap::BAKE_ERROR_NO_SAVE_PATH: { + case LightmapGI::BAKE_ERROR_NO_SAVE_PATH: { String scene_path = lightmap->get_filename(); if (scene_path == String()) { scene_path = lightmap->get_owner()->get_filename(); @@ -57,10 +57,10 @@ void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) { file_dialog->popup_file_dialog(); } break; - case BakedLightmap::BAKE_ERROR_NO_MESHES: + case LightmapGI::BAKE_ERROR_NO_MESHES: EditorNode::get_singleton()->show_warning(TTR("No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake Light' flag is on.")); break; - case BakedLightmap::BAKE_ERROR_CANT_CREATE_IMAGE: + case LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE: EditorNode::get_singleton()->show_warning(TTR("Failed creating lightmap images, make sure path is writable.")); break; default: { @@ -69,12 +69,12 @@ void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) { } } -void BakedLightmapEditorPlugin::_bake() { +void LightmapGIEditorPlugin::_bake() { _bake_select_file(""); } -void BakedLightmapEditorPlugin::edit(Object *p_object) { - BakedLightmap *s = Object::cast_to<BakedLightmap>(p_object); +void LightmapGIEditorPlugin::edit(Object *p_object) { + LightmapGI *s = Object::cast_to<LightmapGI>(p_object); if (!s) { return; } @@ -82,11 +82,11 @@ void BakedLightmapEditorPlugin::edit(Object *p_object) { lightmap = s; } -bool BakedLightmapEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("BakedLightmap"); +bool LightmapGIEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("LightmapGI"); } -void BakedLightmapEditorPlugin::make_visible(bool p_visible) { +void LightmapGIEditorPlugin::make_visible(bool p_visible) { if (p_visible) { bake->show(); } else { @@ -94,9 +94,9 @@ void BakedLightmapEditorPlugin::make_visible(bool p_visible) { } } -EditorProgress *BakedLightmapEditorPlugin::tmp_progress = nullptr; +EditorProgress *LightmapGIEditorPlugin::tmp_progress = nullptr; -bool BakedLightmapEditorPlugin::bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) { +bool LightmapGIEditorPlugin::bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) { if (!tmp_progress) { tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), 1000, false)); ERR_FAIL_COND_V(tmp_progress == nullptr, false); @@ -104,18 +104,18 @@ bool BakedLightmapEditorPlugin::bake_func_step(float p_progress, const String &p return tmp_progress->step(p_description, p_progress * 1000, p_refresh); } -void BakedLightmapEditorPlugin::bake_func_end() { +void LightmapGIEditorPlugin::bake_func_end() { if (tmp_progress != nullptr) { memdelete(tmp_progress); tmp_progress = nullptr; } } -void BakedLightmapEditorPlugin::_bind_methods() { - ClassDB::bind_method("_bake", &BakedLightmapEditorPlugin::_bake); +void LightmapGIEditorPlugin::_bind_methods() { + ClassDB::bind_method("_bake", &LightmapGIEditorPlugin::_bake); } -BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) { +LightmapGIEditorPlugin::LightmapGIEditorPlugin(EditorNode *p_node) { editor = p_node; bake = memnew(Button); bake->set_flat(true); @@ -130,9 +130,9 @@ BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); file_dialog->add_filter("*.lmbake ; LightMap Bake"); file_dialog->set_title(TTR("Select lightmap bake file:")); - file_dialog->connect("file_selected", callable_mp(this, &BakedLightmapEditorPlugin::_bake_select_file)); + file_dialog->connect("file_selected", callable_mp(this, &LightmapGIEditorPlugin::_bake_select_file)); bake->add_child(file_dialog); } -BakedLightmapEditorPlugin::~BakedLightmapEditorPlugin() { +LightmapGIEditorPlugin::~LightmapGIEditorPlugin() { } diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/lightmap_gi_editor_plugin.h index d291c377d9..12d080d6be 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.h +++ b/editor/plugins/lightmap_gi_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* baked_lightmap_editor_plugin.h */ +/* lightmap_gi_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -33,13 +33,13 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" -#include "scene/3d/baked_lightmap.h" +#include "scene/3d/lightmap_gi.h" #include "scene/resources/material.h" -class BakedLightmapEditorPlugin : public EditorPlugin { - GDCLASS(BakedLightmapEditorPlugin, EditorPlugin); +class LightmapGIEditorPlugin : public EditorPlugin { + GDCLASS(LightmapGIEditorPlugin, EditorPlugin); - BakedLightmap *lightmap; + LightmapGI *lightmap; Button *bake; EditorNode *editor; @@ -56,14 +56,14 @@ protected: static void _bind_methods(); public: - virtual String get_name() const override { return "BakedLightmap"; } + virtual String get_name() const override { return "LightmapGI"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override; - BakedLightmapEditorPlugin(EditorNode *p_node); - ~BakedLightmapEditorPlugin(); + LightmapGIEditorPlugin(EditorNode *p_node); + ~LightmapGIEditorPlugin(); }; #endif diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index ad99ad7808..81f0ecacf2 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -119,17 +119,17 @@ MaterialEditor::MaterialEditor() { viewport->set_msaa(Viewport::MSAA_4X); camera = memnew(Camera3D); - camera->set_transform(Transform(Basis(), Vector3(0, 0, 3))); + camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 3))); camera->set_perspective(45, 0.1, 10); camera->make_current(); viewport->add_child(camera); light1 = memnew(DirectionalLight3D); - light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); + light1->set_transform(Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); viewport->add_child(light1); light2 = memnew(DirectionalLight3D); - light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); + light2->set_transform(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); light2->set_color(Color(0.7, 0.7, 0.7)); viewport->add_child(light2); @@ -139,7 +139,7 @@ MaterialEditor::MaterialEditor() { box_instance = memnew(MeshInstance3D); viewport->add_child(box_instance); - Transform box_xform; + Transform3D box_xform; box_xform.basis.rotate(Vector3(1, 0, 0), Math::deg2rad(25.0)); box_xform.basis = box_xform.basis * Basis().rotated(Vector3(0, 1, 0), Math::deg2rad(-25.0)); box_xform.basis.scale(Vector3(0.8, 0.8, 0.8)); diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 9d29c31522..8d488dce20 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -65,7 +65,7 @@ void MeshEditor::_notification(int p_what) { } void MeshEditor::_update_rotation() { - Transform t; + Transform3D t; t.basis.rotate(Vector3(0, 1, 0), -rot_y); t.basis.rotate(Vector3(1, 0, 0), -rot_x); rotation->set_transform(t); @@ -85,7 +85,7 @@ void MeshEditor::edit(Ref<Mesh> p_mesh) { if (m != 0) { m = 1.0 / m; m *= 0.5; - Transform xform; + Transform3D xform; xform.basis.scale(Vector3(m, m, m)); xform.origin = -xform.basis.xform(ofs); //-ofs*m; //xform.origin.z -= aabb.get_longest_axis_size() * 2; @@ -117,16 +117,16 @@ MeshEditor::MeshEditor() { viewport->set_msaa(Viewport::MSAA_2X); set_stretch(true); camera = memnew(Camera3D); - camera->set_transform(Transform(Basis(), Vector3(0, 0, 1.1))); + camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 1.1))); camera->set_perspective(45, 0.1, 10); viewport->add_child(camera); light1 = memnew(DirectionalLight3D); - light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); + light1->set_transform(Transform3D().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); viewport->add_child(light1); light2 = memnew(DirectionalLight3D); - light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); + light2->set_transform(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); light2->set_color(Color(0.7, 0.7, 0.7)); viewport->add_child(light2); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index 6f1f243444..e64992759d 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -127,7 +127,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, continue; } - //Transform shape_transform = sb->shape_owner_get_transform(E->get()); + //Transform3D shape_transform = sb->shape_owner_get_transform(E->get()); //shape_transform.set_origin(shape_transform.get_origin() - phys_offset); @@ -147,7 +147,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, p_library->set_item_shapes(id, collisions); Ref<NavigationMesh> navmesh; - Transform navmesh_transform; + Transform3D navmesh_transform; for (int j = 0; j < mi->get_child_count(); j++) { Node *child2 = mi->get_child(j); if (!Object::cast_to<NavigationRegion3D>(child2)) { @@ -170,7 +170,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (true) { Vector<Ref<Mesh>> meshes; - Vector<Transform> transforms; + Vector<Transform3D> transforms; Vector<int> ids = p_library->get_item_list(); for (int i = 0; i < ids.size(); i++) { if (mesh_instances.find(ids[i])) { diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 19c6dcf402..48b885930f 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -111,7 +111,7 @@ void MultiMeshEditor::_populate() { return; } - Transform geom_xform = node->get_global_transform().affine_inverse() * ss_instance->get_global_transform(); + Transform3D geom_xform = node->get_global_transform().affine_inverse() * ss_instance->get_global_transform(); Vector<Face3> geometry = ss_instance->get_faces(VisualInstance3D::FACES_SOLID); @@ -167,7 +167,7 @@ void MultiMeshEditor::_populate() { float _scale = populate_scale->get_value(); int axis = populate_axis->get_selected(); - Transform axis_xform; + Transform3D axis_xform; if (axis == Vector3::AXIS_Z) { axis_xform.rotate(Vector3(1, 0, 0), -Math_PI * 0.5); } @@ -191,7 +191,7 @@ void MultiMeshEditor::_populate() { Vector3 normal = face.get_plane().normal; Vector3 op_axis = (face.vertex[0] - face.vertex[1]).normalized(); - Transform xform; + Transform3D xform; xform.set_look_at(pos, pos + op_axis, normal); xform = xform * axis_xform; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index ba39ce3aed..6ab15f763f 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -361,8 +361,8 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { } } -Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { - Transform camera_transform; +Transform3D Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { + Transform3D camera_transform; camera_transform.translate(p_cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot); @@ -410,7 +410,7 @@ float Node3DEditorViewport::get_fov() const { return CLAMP(spatial_editor->get_fov(), MIN_FOV, MAX_FOV); } -Transform Node3DEditorViewport::_get_camera_transform() const { +Transform3D Node3DEditorViewport::_get_camera_transform() const { return camera->get_global_transform(); } @@ -631,7 +631,7 @@ Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { } Vector2 screen_he = cm.get_viewport_half_extents(); - Transform camera_transform; + Transform3D camera_transform; camera_transform.translate(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); @@ -829,7 +829,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high Vector3 ray_pos = _get_ray_pos(Vector2(p_screenpos.x, p_screenpos.y)); Vector3 ray = _get_ray(Vector2(p_screenpos.x, p_screenpos.y)); - Transform gt = spatial_editor->get_gizmo_transform(); + Transform3D gt = spatial_editor->get_gizmo_transform(); float gs = gizmo_scale; if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) { @@ -1579,10 +1579,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform original = se->original; - Transform original_local = se->original_local; - Transform base = Transform(Basis(), _edit.center); - Transform t; + Transform3D original = se->original; + Transform3D original_local = se->original_local; + Transform3D base = Transform3D(Basis(), _edit.center); + Transform3D t; Vector3 local_scale; if (local_coords) { @@ -1608,7 +1608,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { motion.snap(Vector3(snap, snap, snap)); } - Transform r; + Transform3D r; r.basis.scale(motion + Vector3(1, 1, 1)); t = base * (r * (base.inverse() * original)); @@ -1701,8 +1701,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform original = se->original; - Transform t; + Transform3D original = se->original; + Transform3D t; if (local_coords) { if (_edit.snap || spatial_editor->is_snap_enabled()) { @@ -1797,10 +1797,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } - Transform t; + Transform3D t; if (local_coords) { - Transform original_local = se->original_local; + Transform3D original_local = se->original_local; Basis rot = Basis(axis, angle); t.basis = original_local.get_basis().orthonormalized() * rot; @@ -1811,9 +1811,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { sp->set_scale(original_local.basis.get_scale()); // re-apply original scale } else { - Transform original = se->original; - Transform r; - Transform base = Transform(Basis(), _edit.center); + Transform3D original = se->original; + Transform3D r; + Transform3D base = Transform3D(Basis(), _edit.center); r.basis.rotate(plane.normal, angle); t = base * r * base.inverse() * original; @@ -2057,7 +2057,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const pan_speed *= pan_speed_modifier; } - Transform camera_transform; + Transform3D camera_transform; camera_transform.translate(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); @@ -2145,7 +2145,7 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const const bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis"); // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". - const Transform prev_camera_transform = to_camera_transform(cursor); + const Transform3D prev_camera_transform = to_camera_transform(cursor); if (invert_y_axis) { cursor.x_rot -= p_relative.y * radians_per_pixel; @@ -2158,7 +2158,7 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const cursor.y_rot += p_relative.x * radians_per_pixel; // Look is like the opposite of Orbit: the focus point rotates around the camera - Transform camera_transform = to_camera_transform(cursor); + Transform3D camera_transform = to_camera_transform(cursor); Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0)); Vector3 diff = prev_pos - pos; @@ -2444,7 +2444,7 @@ void Node3DEditorViewport::_notification(int p_what) { continue; } - Transform t = sp->get_global_gizmo_transform(); + Transform3D t = sp->get_global_gizmo_transform(); VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sp); AABB new_aabb = vi ? vi->get_aabb() : _calculate_spatial_bounds(sp); @@ -2500,9 +2500,9 @@ void Node3DEditorViewport::_notification(int p_what) { if (show_info) { String text; - text += "X: " + rtos(current_camera->get_translation().x).pad_decimals(1) + "\n"; - text += "Y: " + rtos(current_camera->get_translation().y).pad_decimals(1) + "\n"; - text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n"; + text += "X: " + rtos(current_camera->get_position().x).pad_decimals(1) + "\n"; + text += "Y: " + rtos(current_camera->get_position().y).pad_decimals(1) + "\n"; + text += "Z: " + rtos(current_camera->get_position().z).pad_decimals(1) + "\n"; text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n"; text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n"; @@ -2878,7 +2878,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { break; } - Transform camera_transform = camera->get_global_transform(); + Transform3D camera_transform = camera->get_global_transform(); List<Node *> &selection = editor_selection->get_selected_node_list(); @@ -2895,7 +2895,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { continue; } - Transform xform; + Transform3D xform; if (orthogonal) { xform = sp->get_global_transform(); xform.basis.set_euler(camera_transform.basis.get_euler()); @@ -2915,7 +2915,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { break; } - Transform camera_transform = camera->get_global_transform(); + Transform3D camera_transform = camera->get_global_transform(); List<Node *> &selection = editor_selection->get_selected_node_list(); @@ -3060,9 +3060,9 @@ void Node3DEditorViewport::_menu_option(int p_option) { case VIEW_DISPLAY_NORMAL_BUFFER: case VIEW_DISPLAY_DEBUG_SHADOW_ATLAS: case VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS: - case VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO: - case VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING: - case VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION: + case VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO: + case VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING: + case VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION: case VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE: case VIEW_DISPLAY_DEBUG_SSAO: case VIEW_DISPLAY_DEBUG_PSSM_SPLITS: @@ -3086,9 +3086,9 @@ void Node3DEditorViewport::_menu_option(int p_option) { VIEW_DISPLAY_WIREFRAME, VIEW_DISPLAY_DEBUG_SHADOW_ATLAS, VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS, - VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO, - VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING, - VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION, + VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO, + VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING, + VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION, VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE, VIEW_DISPLAY_DEBUG_SSAO, VIEW_DISPLAY_DEBUG_GI_BUFFER, @@ -3114,9 +3114,9 @@ void Node3DEditorViewport::_menu_option(int p_option) { Viewport::DEBUG_DRAW_WIREFRAME, Viewport::DEBUG_DRAW_SHADOW_ATLAS, Viewport::DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, - Viewport::DEBUG_DRAW_GI_PROBE_ALBEDO, - Viewport::DEBUG_DRAW_GI_PROBE_LIGHTING, - Viewport::DEBUG_DRAW_GI_PROBE_EMISSION, + Viewport::DEBUG_DRAW_VOXEL_GI_ALBEDO, + Viewport::DEBUG_DRAW_VOXEL_GI_LIGHTING, + Viewport::DEBUG_DRAW_VOXEL_GI_EMISSION, Viewport::DEBUG_DRAW_SCENE_LUMINANCE, Viewport::DEBUG_DRAW_SSAO, Viewport::DEBUG_DRAW_GI_BUFFER, @@ -3315,9 +3315,9 @@ void Node3DEditorViewport::update_transform_gizmo_view() { return; } - Transform xform = spatial_editor->get_gizmo_transform(); + Transform3D xform = spatial_editor->get_gizmo_transform(); - Transform camera_xform = camera->get_transform(); + Transform3D camera_xform = camera->get_transform(); if (xform.origin.distance_squared_to(camera_xform.origin) < 0.01) { for (int i = 0; i < 3; i++) { @@ -3800,7 +3800,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po Node3D *node3d = Object::cast_to<Node3D>(instanced_scene); if (node3d) { - Transform global_transform; + Transform3D global_transform; Node3D *parent_node3d = Object::cast_to<Node3D>(parent); if (parent_node3d) { global_transform = parent_node3d->get_global_gizmo_transform(); @@ -3900,7 +3900,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant } if (can_instance) { - Transform global_transform = Transform(Basis(), _get_instance_position(p_point)); + Transform3D global_transform = Transform3D(Basis(), _get_instance_position(p_point)); preview_node->set_global_transform(global_transform); } @@ -4036,9 +4036,9 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Decal Atlas"), VIEW_DISPLAY_DEBUG_DECAL_ATLAS); display_submenu->add_separator(); - display_submenu->add_radio_check_item(TTR("GIProbe Lighting"), VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING); - display_submenu->add_radio_check_item(TTR("GIProbe Albedo"), VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO); - display_submenu->add_radio_check_item(TTR("GIProbe Emission"), VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION); + display_submenu->add_radio_check_item(TTR("VoxelGI Lighting"), VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING); + display_submenu->add_radio_check_item(TTR("VoxelGI Albedo"), VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO); + display_submenu->add_radio_check_item(TTR("VoxelGI Emission"), VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("SDFGI Cascades"), VIEW_DISPLAY_DEBUG_SDFGI); display_submenu->add_radio_check_item(TTR("SDFGI Probes"), VIEW_DISPLAY_DEBUG_SDFGI_PROBES); @@ -4574,7 +4574,7 @@ void Node3DEditor::update_transform_gizmo() { continue; } - Transform xf = se->sp->get_global_gizmo_transform(); + Transform3D xf = se->sp->get_global_gizmo_transform(); if (first) { center.position = xf.origin; @@ -4955,7 +4955,7 @@ void Node3DEditor::_snap_update() { } void Node3DEditor::_xform_dialog_action() { - Transform t; + Transform3D t; //translation Vector3 scale; Vector3 rotate; @@ -4988,7 +4988,7 @@ void Node3DEditor::_xform_dialog_action() { bool post = xform_type->get_selected() > 0; - Transform tr = sp->get_global_gizmo_transform(); + Transform3D tr = sp->get_global_gizmo_transform(); if (post) { tr = tr * t; } else { @@ -5834,7 +5834,7 @@ void Node3DEditor::_init_grid() { return; } Camera3D *camera = get_editor_viewport(0)->camera; - Vector3 camera_position = camera->get_translation(); + Vector3 camera_position = camera->get_position(); if (camera_position == Vector3()) { return; // Camera3D is invalid, don't draw the grid. } @@ -6180,7 +6180,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() { if (ss->intersect_ray(from, to, result, excluded)) { Vector3 position_offset = d["position_offset"]; - Transform new_transform = sp->get_global_transform(); + Transform3D new_transform = sp->get_global_transform(); new_transform.origin.y = result.position.y; new_transform.origin = new_transform.origin - position_offset; @@ -6496,8 +6496,8 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<CPUParticles3DGizmoPlugin>(memnew(CPUParticles3DGizmoPlugin))); add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin))); add_gizmo_plugin(Ref<DecalGizmoPlugin>(memnew(DecalGizmoPlugin))); - add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin))); - add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin))); + add_gizmo_plugin(Ref<VoxelGIGizmoPlugin>(memnew(VoxelGIGizmoPlugin))); + add_gizmo_plugin(Ref<LightmapGIGizmoPlugin>(memnew(LightmapGIGizmoPlugin))); add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin))); add_gizmo_plugin(Ref<CollisionObject3DGizmoPlugin>(memnew(CollisionObject3DGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); @@ -6556,7 +6556,7 @@ void Node3DEditor::_preview_settings_changed() { } { // preview sun - Transform t; + Transform3D t; t.basis = sun_rotation; preview_sun->set_transform(t); sun_direction->update(); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 33f4c32471..c68857cd7e 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -206,9 +206,9 @@ class Node3DEditorViewport : public Control { VIEW_DISPLAY_NORMAL_BUFFER, VIEW_DISPLAY_DEBUG_SHADOW_ATLAS, VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS, - VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO, - VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING, - VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION, + VIEW_DISPLAY_DEBUG_VOXEL_GI_ALBEDO, + VIEW_DISPLAY_DEBUG_VOXEL_GI_LIGHTING, + VIEW_DISPLAY_DEBUG_VOXEL_GI_EMISSION, VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE, VIEW_DISPLAY_DEBUG_SSAO, VIEW_DISPLAY_DEBUG_PSSM_SPLITS, @@ -322,7 +322,7 @@ private: Vector3 _get_ray_pos(const Vector2 &p_pos) const; Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); - Transform _get_camera_transform() const; + Transform3D _get_camera_transform() const; int get_selected_count() const; Vector3 _get_camera_position() const; @@ -380,7 +380,7 @@ private: struct EditData { TransformMode mode; TransformPlane plane; - Transform original; + Transform3D original; Vector3 click_ray; Vector3 click_ray_pos; Vector3 center; @@ -432,7 +432,7 @@ private: // void _update_camera(float p_interp_delta); - Transform to_camera_transform(const Cursor &p_cursor) const; + Transform3D to_camera_transform(const Cursor &p_cursor) const; void _draw(); void _surface_mouse_enter(); @@ -505,9 +505,9 @@ class Node3DEditorSelectedItem : public Object { public: AABB aabb; - Transform original; // original location when moving - Transform original_local; - Transform last_xform; // last transform + Transform3D original; // original location when moving + Transform3D original_local; + Transform3D last_xform; // last transform bool last_xform_dirty; Node3D *sp; RID sbox_instance; @@ -641,7 +641,7 @@ private: struct Gizmo { bool visible = false; float scale = 0; - Transform transform; + Transform3D transform; } gizmo; enum MenuOption { @@ -824,7 +824,7 @@ public: float get_zfar() const { return settings_zfar->get_value(); } float get_fov() const { return settings_fov->get_value(); } - Transform get_gizmo_transform() const { return gizmo.transform; } + Transform3D get_gizmo_transform() const { return gizmo.transform; } bool is_gizmo_visible() const { return gizmo.visible; } ToolMode get_tool_mode() const { return tool_mode; } diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 8c73294723..b0eb13c3c6 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -94,8 +94,8 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin return; } - Transform gt = path->get_global_transform(); - Transform gi = gt.affine_inverse(); + Transform3D gt = path->get_global_transform(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -302,8 +302,8 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref if (c.is_null()) { return false; } - Transform gt = path->get_global_transform(); - Transform it = gt.affine_inverse(); + Transform3D gt = path->get_global_transform(); + Transform3D it = gt.affine_inverse(); static const int click_dist = 10; //should make global diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 6d82685c05..d2ea7a10dc 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -1144,7 +1144,7 @@ void Polygon2DEditor::_uv_draw() { if (!found_child) { //draw normally Transform2D bone_xform = node->get_global_transform().affine_inverse() * (skeleton->get_global_transform() * bone->get_skeleton_rest()); - Transform2D endpoint_xform = bone_xform * Transform2D(0, Vector2(bone->get_default_length(), 0)); + Transform2D endpoint_xform = bone_xform * Transform2D(0, Vector2(bone->get_length(), 0)); Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5); uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE)); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 57bd551c43..d66217ec2d 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2454,7 +2454,9 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const script_list->select(script_list->find_metadata(i)); // Save the current script so the changes can be picked up by an external editor. - save_current_script(); + if (!_is_built_in_script(script.ptr())) { // But only if it's not built-in script. + save_current_script(); + } break; } @@ -3191,7 +3193,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb if (ResourceLoader::exists(fpath)) { RES res = ResourceLoader::load(fpath); - if (fpath.get_extension() == "shader") { + if (fpath.get_extension() == "gdshader") { ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader")); shader_editor->edit(res.ptr()); shader_editor->make_visible(true); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 404ef62eca..6dc98503ca 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -95,7 +95,7 @@ void BoneTransformEditor::create_editors() { section->get_vbox()->add_child(transform_section); // Transform/Matrix property - transform_property = memnew(EditorPropertyTransform()); + transform_property = memnew(EditorPropertyTransform3D()); transform_property->setup(-10000, 10000, 0.001f, true); transform_property->set_label("Transform"); transform_property->set_use_folding(true); @@ -171,7 +171,7 @@ void BoneTransformEditor::_value_changed(const double p_value) { return; } - Transform tform = compute_transform_from_vector3s(); + Transform3D tform = compute_transform_from_vector3s(); _change_transform(tform); } @@ -179,30 +179,30 @@ void BoneTransformEditor::_value_changed_vector3(const String p_property_name, c if (updating) { return; } - Transform tform = compute_transform_from_vector3s(); + Transform3D tform = compute_transform_from_vector3s(); _change_transform(tform); } -Transform BoneTransformEditor::compute_transform_from_vector3s() const { +Transform3D BoneTransformEditor::compute_transform_from_vector3s() const { // Convert rotation from degrees to radians. Vector3 prop_rotation = rotation_property->get_vector(); prop_rotation.x = Math::deg2rad(prop_rotation.x); prop_rotation.y = Math::deg2rad(prop_rotation.y); prop_rotation.z = Math::deg2rad(prop_rotation.z); - return Transform( + return Transform3D( Basis(prop_rotation, scale_property->get_vector()), translation_property->get_vector()); } -void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform p_transform, const StringName p_edited_property_name, const bool p_boolean) { +void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean) { if (updating) { return; } _change_transform(p_transform); } -void BoneTransformEditor::_change_transform(Transform p_new_transform) { +void BoneTransformEditor::_change_transform(Transform3D p_new_transform) { if (property.get_slicec('/', 0) == "bones" && property.get_slicec('/', 2) == "custom_pose") { undo_redo->create_action(TTR("Set Custom Bone Pose Transform"), UndoRedo::MERGE_ENDS); undo_redo->add_undo_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_custom_pose(property.get_slicec('/', 1).to_int())); @@ -235,7 +235,7 @@ void BoneTransformEditor::_update_properties() { updating = true; - Transform tform = skeleton->get(property); + Transform3D tform = skeleton->get(property); _update_transform_properties(tform); } @@ -250,11 +250,11 @@ void BoneTransformEditor::_update_custom_pose_properties() { updating = true; - Transform tform = skeleton->get_bone_custom_pose(property.to_int()); + Transform3D tform = skeleton->get_bone_custom_pose(property.to_int()); _update_transform_properties(tform); } -void BoneTransformEditor::_update_transform_properties(Transform tform) { +void BoneTransformEditor::_update_transform_properties(Transform3D tform) { Basis rotation_basis = tform.get_basis(); Vector3 rotation_radians = rotation_basis.get_rotation_euler(); Vector3 rotation_degrees = Vector3(Math::rad2deg(rotation_radians.x), Math::rad2deg(rotation_radians.y), Math::rad2deg(rotation_radians.z)); @@ -306,7 +306,7 @@ void BoneTransformEditor::_key_button_pressed() { } // Need to normalize the basis before you key it - Transform tform = compute_transform_from_vector3s(); + Transform3D tform = compute_transform_from_vector3s(); tform.orthonormalize(); AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(skeleton, name, tform); } @@ -380,7 +380,7 @@ void Skeleton3DEditor::create_physical_skeleton() { } PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos) { - const Transform child_rest = skeleton->get_bone_rest(bone_child_id); + const Transform3D child_rest = skeleton->get_bone_rest(bone_child_id); const real_t half_height(child_rest.origin.length() * 0.5); const real_t radius(half_height * 0.2); @@ -392,15 +392,15 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi CollisionShape3D *bone_shape = memnew(CollisionShape3D); bone_shape->set_shape(bone_shape_capsule); - Transform capsule_transform; + Transform3D capsule_transform; capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0)); bone_shape->set_transform(capsule_transform); - Transform body_transform; + Transform3D body_transform; body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin); body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height)); - Transform joint_transform; + Transform3D joint_transform; joint_transform.origin = Vector3(0, 0, half_height); PhysicalBone3D *physical_bone = memnew(PhysicalBone3D); diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index 14c213f7b2..9de52c6fa8 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -41,7 +41,7 @@ class PhysicalBone3D; class Skeleton3DEditorPlugin; class Button; class CheckBox; -class EditorPropertyTransform; +class EditorPropertyTransform3D; class EditorPropertyVector3; class BoneTransformEditor : public VBoxContainer { @@ -53,7 +53,7 @@ class BoneTransformEditor : public VBoxContainer { EditorPropertyVector3 *rotation_property = nullptr; EditorPropertyVector3 *scale_property = nullptr; EditorInspectorSection *transform_section = nullptr; - EditorPropertyTransform *transform_property = nullptr; + EditorPropertyTransform3D *transform_property = nullptr; Rect2 background_rects[5]; @@ -78,11 +78,11 @@ class BoneTransformEditor : public VBoxContainer { // Called when the one of the EditorPropertyVector3 are updated. void _value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean); // Called when the transform_property is updated. - void _value_changed_transform(const String p_property_name, const Transform p_transform, const StringName p_edited_property_name, const bool p_boolean); + void _value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean); // Changes the transform to the given transform and updates the UI accordingly. - void _change_transform(Transform p_new_transform); + void _change_transform(Transform3D p_new_transform); // Creates a Transform using the EditorPropertyVector3 properties. - Transform compute_transform_from_vector3s() const; + Transform3D compute_transform_from_vector3s() const; void update_enabled_checkbox(); @@ -98,7 +98,7 @@ public: void _update_properties(); void _update_custom_pose_properties(); - void _update_transform_properties(Transform p_transform); + void _update_transform_properties(Transform3D p_transform); // Can/cannot modify the spinner values for the Transform void set_read_only(const bool p_read_only); @@ -127,7 +127,7 @@ class Skeleton3DEditor : public VBoxContainer { struct BoneInfo { PhysicalBone3D *physical_bone = nullptr; - Transform relative_rest; // Relative to skeleton node + Transform3D relative_rest; // Relative to skeleton node }; EditorNode *editor; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 0e554a4991..dc7f85a790 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -542,7 +542,7 @@ TextEditor::TextEditor() { edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextEditor::_edit_option)); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("un_redo"), EDIT_REDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 98e1a1489e..2bb9e64262 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -44,6 +44,7 @@ #include "scene/gui/panel.h" #include "scene/main/window.h" #include "scene/resources/visual_shader_nodes.h" +#include "scene/resources/visual_shader_particle_nodes.h" #include "scene/resources/visual_shader_sdf_nodes.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" @@ -417,6 +418,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } + Ref<VisualShaderNodeParticleEmit> emit = vsnode; + if (emit.is_valid()) { + node->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + } + Ref<VisualShaderNodeUniform> uniform = vsnode; if (uniform.is_valid()) { VisualShaderEditor::get_singleton()->graph->add_child(node); @@ -1013,13 +1019,13 @@ bool VisualShaderEditor::_is_available(int p_mode) { if (p_mode != -1) { switch (current_mode) { - case 0: // Vertex or Emit + case 0: // Vertex / Emit current_mode = 1; break; - case 1: // Fragment or Process + case 1: // Fragment / Process current_mode = 2; break; - case 2: // Light or End + case 2: // Light / Collide current_mode = 4; break; default: @@ -1235,22 +1241,29 @@ void VisualShaderEditor::_update_options_menu() { void VisualShaderEditor::_set_mode(int p_which) { if (p_which == VisualShader::MODE_SKY) { - edit_type_standart->set_visible(false); + edit_type_standard->set_visible(false); edit_type_particles->set_visible(false); edit_type_sky->set_visible(true); edit_type = edit_type_sky; + custom_mode_box->set_visible(false); mode = MODE_FLAGS_SKY; } else if (p_which == VisualShader::MODE_PARTICLES) { - edit_type_standart->set_visible(false); + edit_type_standard->set_visible(false); edit_type_particles->set_visible(true); edit_type_sky->set_visible(false); edit_type = edit_type_particles; + if ((edit_type->get_selected() + 3) > VisualShader::TYPE_PROCESS) { + custom_mode_box->set_visible(false); + } else { + custom_mode_box->set_visible(true); + } mode = MODE_FLAGS_PARTICLES; } else { edit_type_particles->set_visible(false); - edit_type_standart->set_visible(true); + edit_type_standard->set_visible(true); edit_type_sky->set_visible(false); - edit_type = edit_type_standart; + edit_type = edit_type_standard; + custom_mode_box->set_visible(false); mode = MODE_FLAGS_SPATIAL_CANVASITEM; } visual_shader->set_shader_type(get_current_shader_type()); @@ -1403,9 +1416,9 @@ void VisualShaderEditor::_update_graph() { VisualShader::Type VisualShaderEditor::get_current_shader_type() const { VisualShader::Type type; if (mode & MODE_FLAGS_PARTICLES) { - type = VisualShader::Type(edit_type->get_selected() + 3); + type = VisualShader::Type(edit_type->get_selected() + 3 + (custom_mode_enabled ? 3 : 0)); } else if (mode & MODE_FLAGS_SKY) { - type = VisualShader::Type(edit_type->get_selected() + 6); + type = VisualShader::Type(edit_type->get_selected() + 8); } else { type = VisualShader::Type(edit_type->get_selected()); } @@ -2081,6 +2094,16 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { } } + //UV_FUNC + { + VisualShaderNodeUVFunc *uvFunc = Object::cast_to<VisualShaderNodeUVFunc>(p_node); + + if (uvFunc) { + uvFunc->set_function((VisualShaderNodeUVFunc::Function)p_op_idx); + return; + } + } + // IS { VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node); @@ -2949,9 +2972,6 @@ void VisualShaderEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { highend_label->set_modulate(get_theme_color("vulkan_color", "Editor")); - error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree")); - error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); - node_filter->set_right_icon(Control::get_theme_icon("Search", "EditorIcons")); preview_shader->set_icon(Control::get_theme_icon("Shader", "EditorIcons")); @@ -2992,9 +3012,10 @@ void VisualShaderEditor::_notification(int p_what) { preview_text->add_comment_delimiter("/*", "*/", false); preview_text->add_comment_delimiter("//", "", true); - error_text->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts")); - error_text->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts")); - error_text->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); + error_panel->add_theme_style_override("panel", get_theme_stylebox("panel", "Panel")); + error_label->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts")); + error_label->add_theme_font_size_override("font_size", get_theme_font_size("status_source_size", "EditorFonts")); + error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor")); } tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Tools", "EditorIcons")); @@ -3216,8 +3237,18 @@ void VisualShaderEditor::_mode_selected(int p_id) { int offset = 0; if (mode & MODE_FLAGS_PARTICLES) { offset = 3; + if (p_id + offset > VisualShader::TYPE_PROCESS) { + custom_mode_box->set_visible(false); + custom_mode_enabled = false; + } else { + custom_mode_box->set_visible(true); + if (custom_mode_box->is_pressed()) { + custom_mode_enabled = true; + offset += 3; + } + } } else if (mode & MODE_FLAGS_SKY) { - offset = 6; + offset = 8; } visual_shader->set_shader_type(VisualShader::Type(p_id + offset)); @@ -3225,6 +3256,21 @@ void VisualShaderEditor::_mode_selected(int p_id) { _update_graph(); } +void VisualShaderEditor::_custom_mode_toggled(bool p_enabled) { + if (!(mode & MODE_FLAGS_PARTICLES)) { + return; + } + custom_mode_enabled = p_enabled; + int id = edit_type->get_selected() + 3; + if (p_enabled) { + visual_shader->set_shader_type(VisualShader::Type(id + 3)); + } else { + visual_shader->set_shader_type(VisualShader::Type(id)); + } + _update_options_menu(); + _update_graph(); +} + void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, String p_name) { String prev_name = p_input->get_input_name(); @@ -3610,13 +3656,13 @@ void VisualShaderEditor::_update_preview() { if (err != OK) { Color error_line_color = EDITOR_GET("text_editor/highlighting/mark_color"); preview_text->set_line_background_color(sl.get_error_line() - 1, error_line_color); - error_text->set_visible(true); + error_panel->show(); String text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); - error_text->set_text(text); + error_label->set_text(text); shader_error = true; } else { - error_text->set_visible(false); + error_panel->hide(); shader_error = false; } } @@ -3723,17 +3769,23 @@ VisualShaderEditor::VisualShaderEditor() { graph->get_zoom_hbox()->add_child(vs); graph->get_zoom_hbox()->move_child(vs, 0); - edit_type_standart = memnew(OptionButton); - edit_type_standart->add_item(TTR("Vertex")); - edit_type_standart->add_item(TTR("Fragment")); - edit_type_standart->add_item(TTR("Light")); - edit_type_standart->select(1); - edit_type_standart->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); + custom_mode_box = memnew(CheckBox); + custom_mode_box->set_text(TTR("Custom")); + custom_mode_box->set_pressed(false); + custom_mode_box->set_visible(false); + custom_mode_box->connect("toggled", callable_mp(this, &VisualShaderEditor::_custom_mode_toggled)); + + edit_type_standard = memnew(OptionButton); + edit_type_standard->add_item(TTR("Vertex")); + edit_type_standard->add_item(TTR("Fragment")); + edit_type_standard->add_item(TTR("Light")); + edit_type_standard->select(1); + edit_type_standard->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); edit_type_particles = memnew(OptionButton); - edit_type_particles->add_item(TTR("Emit")); + edit_type_particles->add_item(TTR("Start")); edit_type_particles->add_item(TTR("Process")); - edit_type_particles->add_item(TTR("End")); + edit_type_particles->add_item(TTR("Collide")); edit_type_particles->select(0); edit_type_particles->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); @@ -3742,14 +3794,16 @@ VisualShaderEditor::VisualShaderEditor() { edit_type_sky->select(0); edit_type_sky->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected)); - edit_type = edit_type_standart; + edit_type = edit_type_standard; + graph->get_zoom_hbox()->add_child(custom_mode_box); + graph->get_zoom_hbox()->move_child(custom_mode_box, 0); + graph->get_zoom_hbox()->add_child(edit_type_standard); + graph->get_zoom_hbox()->move_child(edit_type_standard, 0); graph->get_zoom_hbox()->add_child(edit_type_particles); graph->get_zoom_hbox()->move_child(edit_type_particles, 0); graph->get_zoom_hbox()->add_child(edit_type_sky); graph->get_zoom_hbox()->move_child(edit_type_sky, 0); - graph->get_zoom_hbox()->add_child(edit_type_standart); - graph->get_zoom_hbox()->move_child(edit_type_standart, 0); add_node = memnew(Button); add_node->set_flat(true); @@ -3778,6 +3832,7 @@ VisualShaderEditor::VisualShaderEditor() { preview_vbox = memnew(VBoxContainer); preview_window->add_child(preview_vbox); + preview_vbox->add_theme_constant_override("separation", 0); preview_text = memnew(CodeEdit); syntax_highlighter.instance(); @@ -3787,10 +3842,13 @@ VisualShaderEditor::VisualShaderEditor() { preview_text->set_draw_line_numbers(true); preview_text->set_readonly(true); - error_text = memnew(Label); - preview_vbox->add_child(error_text); - error_text->set_autowrap(true); - error_text->set_visible(false); + error_panel = memnew(PanelContainer); + preview_vbox->add_child(error_panel); + error_panel->set_visible(false); + + error_label = memnew(Label); + error_panel->add_child(error_label); + error_label->set_autowrap(true); /////////////////////////////////////// // POPUP MENU @@ -3965,9 +4023,10 @@ VisualShaderEditor::VisualShaderEditor() { // INPUT + const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes."); + // SPATIAL-FOR-ALL - const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes."); add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); @@ -3986,6 +4045,23 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + // PARTICLES-FOR-ALL + + add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), "attractor_force", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES)); + ///////////////// add_options.push_back(AddOption("Input", "Input", "Common", "VisualShaderNodeInput", TTR("Input parameter."))); @@ -3998,11 +4074,12 @@ VisualShaderEditor::VisualShaderEditor() { const String input_param_for_sky_shader_mode = TTR("'%s' input parameter for sky shader mode."); const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode."); const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode."); - const String input_param_for_emit_shader_mode = TTR("'%s' input parameter for emit shader mode."); + const String input_param_for_start_shader_mode = TTR("'%s' input parameter for start shader mode."); const String input_param_for_process_shader_mode = TTR("'%s' input parameter for process shader mode."); - const String input_param_for_end_shader_mode = TTR("'%s' input parameter for end shader mode."); - const String input_param_for_emit_and_process_shader_mode = TTR("'%s' input parameter for emit and process shader mode."); - const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode."); + const String input_param_for_collide_shader_mode = TTR("'%s' input parameter for collide shader mode."); + const String input_param_for_start_and_process_shader_mode = TTR("'%s' input parameter for start and process shader modes."); + const String input_param_for_process_and_collide_shader_mode = TTR("'%s' input parameter for process and collide shader modes."); + const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader modes."); add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL)); @@ -4079,50 +4156,6 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM)); - // PARTICLES INPUTS - - add_options.push_back(AddOption("Active", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); - - add_options.push_back(AddOption("Active", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); - - add_options.push_back(AddOption("Active", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES)); - // SKY INPUTS add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY)); @@ -4155,6 +4188,22 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY)); + // PARTICLES + + add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), "collision_depth", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), "collision_normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + + add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, -1, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", "A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters.", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES)); + + add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + + add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES)); + // SCALAR add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -4242,6 +4291,8 @@ VisualShaderEditor::VisualShaderEditor() { // TEXTURES + add_options.push_back(AddOption("UVFunc", "Textures", "Common", "VisualShaderNodeUVFunc", TTR("Function to be applied on texture coordinates."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + cubemap_node_option_idx = add_options.size(); add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); curve_node_option_idx = add_options.size(); @@ -4252,6 +4303,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1)); texture3d_node_option_idx = add_options.size(); add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1)); + add_options.push_back(AddOption("UVPanning", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply panning function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_PANNING, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("UVScaling", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply scaling function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_SCALING, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1)); add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1)); @@ -4371,13 +4424,6 @@ VisualShaderEditor::VisualShaderEditor() { _update_options_menu(); - error_panel = memnew(PanelContainer); - add_child(error_panel); - error_label = memnew(Label); - error_panel->add_child(error_label); - error_label->set_text("eh"); - error_panel->hide(); - undo_redo = EditorNode::get_singleton()->get_undo_redo(); Ref<VisualShaderNodePluginDefault> default_plugin; @@ -4694,7 +4740,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par if (Object::cast_to<EditorPropertyResource>(prop)) { Object::cast_to<EditorPropertyResource>(prop)->set_use_sub_inspector(false); prop->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - } else if (Object::cast_to<EditorPropertyTransform>(prop) || Object::cast_to<EditorPropertyVector3>(prop)) { + } else if (Object::cast_to<EditorPropertyTransform3D>(prop) || Object::cast_to<EditorPropertyVector3>(prop)) { prop->set_custom_minimum_size(Size2(250 * EDSCALE, 0)); } else if (Object::cast_to<EditorPropertyFloat>(prop)) { prop->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index b3510aafa1..ad57850e9d 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -142,12 +142,11 @@ class VisualShaderEditor : public VBoxContainer { Button *preview_shader; OptionButton *edit_type = nullptr; - OptionButton *edit_type_standart; + OptionButton *edit_type_standard; OptionButton *edit_type_particles; OptionButton *edit_type_sky; - - PanelContainer *error_panel; - Label *error_label; + CheckBox *custom_mode_box; + bool custom_mode_enabled = false; bool pending_update_preview; bool shader_error; @@ -155,7 +154,8 @@ class VisualShaderEditor : public VBoxContainer { VBoxContainer *preview_vbox; CodeEdit *preview_text; Ref<CodeHighlighter> syntax_highlighter; - Label *error_text; + PanelContainer *error_panel; + Label *error_label; UndoRedo *undo_redo; Point2 saved_node_pos; @@ -191,7 +191,9 @@ class VisualShaderEditor : public VBoxContainer { enum ParticlesTypeFlags { TYPE_FLAGS_EMIT = 1, TYPE_FLAGS_PROCESS = 2, - TYPE_FLAGS_END = 4 + TYPE_FLAGS_COLLIDE = 4, + TYPE_FLAGS_EMIT_CUSTOM = 8, + TYPE_FLAGS_PROCESS_CUSTOM = 16, }; enum SkyTypeFlags { @@ -387,6 +389,7 @@ class VisualShaderEditor : public VBoxContainer { Ref<VisualShaderGraphPlugin> graph_plugin; void _mode_selected(int p_id); + void _custom_mode_toggled(bool p_enabled); void _input_select_item(Ref<VisualShaderNodeInput> input, String name); void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name); diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index f309c5da01..d30cc7ad17 100644 --- a/editor/plugins/gi_probe_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gi_probe_editor_plugin.cpp */ +/* voxel_gi_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,49 +28,49 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gi_probe_editor_plugin.h" +#include "voxel_gi_editor_plugin.h" -void GIProbeEditorPlugin::_bake() { - if (gi_probe) { - if (gi_probe->get_probe_data().is_null()) { +void VoxelGIEditorPlugin::_bake() { + if (voxel_gi) { + if (voxel_gi->get_probe_data().is_null()) { String path = get_tree()->get_edited_scene_root()->get_filename(); if (path == String()) { - path = "res://" + gi_probe->get_name() + "_data.res"; + path = "res://" + voxel_gi->get_name() + "_data.res"; } else { String ext = path.get_extension(); - path = path.get_basename() + "." + gi_probe->get_name() + "_data.res"; + path = path.get_basename() + "." + voxel_gi->get_name() + "_data.res"; } probe_file->set_current_path(path); probe_file->popup_file_dialog(); return; } - gi_probe->bake(); + voxel_gi->bake(); } } -void GIProbeEditorPlugin::edit(Object *p_object) { - GIProbe *s = Object::cast_to<GIProbe>(p_object); +void VoxelGIEditorPlugin::edit(Object *p_object) { + VoxelGI *s = Object::cast_to<VoxelGI>(p_object); if (!s) { return; } - gi_probe = s; + voxel_gi = s; } -bool GIProbeEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("GIProbe"); +bool VoxelGIEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("VoxelGI"); } -void GIProbeEditorPlugin::_notification(int p_what) { +void VoxelGIEditorPlugin::_notification(int p_what) { if (p_what == NOTIFICATION_PROCESS) { - if (!gi_probe) { + if (!voxel_gi) { return; } - const Vector3i size = gi_probe->get_estimated_cell_size(); + const Vector3i size = voxel_gi->get_estimated_cell_size(); String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z); int data_size = 4; - if (GLOBAL_GET("rendering/quality/gi_probes/anisotropic")) { + if (GLOBAL_GET("rendering/quality/voxel_gi/anisotropic")) { data_size += 4; } const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0); @@ -98,7 +98,7 @@ void GIProbeEditorPlugin::_notification(int p_what) { } } -void GIProbeEditorPlugin::make_visible(bool p_visible) { +void VoxelGIEditorPlugin::make_visible(bool p_visible) { if (p_visible) { bake_hb->show(); set_process(true); @@ -108,38 +108,38 @@ void GIProbeEditorPlugin::make_visible(bool p_visible) { } } -EditorProgress *GIProbeEditorPlugin::tmp_progress = nullptr; +EditorProgress *VoxelGIEditorPlugin::tmp_progress = nullptr; -void GIProbeEditorPlugin::bake_func_begin(int p_steps) { +void VoxelGIEditorPlugin::bake_func_begin(int p_steps) { ERR_FAIL_COND(tmp_progress != nullptr); tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake GI Probe"), p_steps)); } -void GIProbeEditorPlugin::bake_func_step(int p_step, const String &p_description) { +void VoxelGIEditorPlugin::bake_func_step(int p_step, const String &p_description) { ERR_FAIL_COND(tmp_progress == nullptr); tmp_progress->step(p_description, p_step, false); } -void GIProbeEditorPlugin::bake_func_end() { +void VoxelGIEditorPlugin::bake_func_end() { ERR_FAIL_COND(tmp_progress == nullptr); memdelete(tmp_progress); tmp_progress = nullptr; } -void GIProbeEditorPlugin::_giprobe_save_path_and_bake(const String &p_path) { +void VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake(const String &p_path) { probe_file->hide(); - if (gi_probe) { - gi_probe->bake(); - ERR_FAIL_COND(gi_probe->get_probe_data().is_null()); - ResourceSaver::save(p_path, gi_probe->get_probe_data(), ResourceSaver::FLAG_CHANGE_PATH); + if (voxel_gi) { + voxel_gi->bake(); + ERR_FAIL_COND(voxel_gi->get_probe_data().is_null()); + ResourceSaver::save(p_path, voxel_gi->get_probe_data(), ResourceSaver::FLAG_CHANGE_PATH); } } -void GIProbeEditorPlugin::_bind_methods() { +void VoxelGIEditorPlugin::_bind_methods() { } -GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) { +VoxelGIEditorPlugin::VoxelGIEditorPlugin(EditorNode *p_node) { editor = p_node; bake_hb = memnew(HBoxContainer); bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -148,7 +148,7 @@ GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) { bake->set_flat(true); bake->set_icon(editor->get_gui_base()->get_theme_icon("Bake", "EditorIcons")); bake->set_text(TTR("Bake GI Probe")); - bake->connect("pressed", callable_mp(this, &GIProbeEditorPlugin::_bake)); + bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake)); bake_hb->add_child(bake); bake_info = memnew(Label); bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -156,18 +156,18 @@ GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) { bake_hb->add_child(bake_info); add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb); - gi_probe = nullptr; + voxel_gi = nullptr; probe_file = memnew(EditorFileDialog); probe_file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); probe_file->add_filter("*.res"); - probe_file->connect("file_selected", callable_mp(this, &GIProbeEditorPlugin::_giprobe_save_path_and_bake)); + probe_file->connect("file_selected", callable_mp(this, &VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake)); get_editor_interface()->get_base_control()->add_child(probe_file); - probe_file->set_title(TTR("Select path for GIProbe Data File")); + probe_file->set_title(TTR("Select path for VoxelGI Data File")); - GIProbe::bake_begin_function = bake_func_begin; - GIProbe::bake_step_function = bake_func_step; - GIProbe::bake_end_function = bake_func_end; + VoxelGI::bake_begin_function = bake_func_begin; + VoxelGI::bake_step_function = bake_func_step; + VoxelGI::bake_end_function = bake_func_end; } -GIProbeEditorPlugin::~GIProbeEditorPlugin() { +VoxelGIEditorPlugin::~VoxelGIEditorPlugin() { } diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h index fdf0623561..4d3cfe90f6 100644 --- a/editor/plugins/gi_probe_editor_plugin.h +++ b/editor/plugins/voxel_gi_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gi_probe_editor_plugin.h */ +/* voxel_gi_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GIPROBEEDITORPLUGIN_H -#define GIPROBEEDITORPLUGIN_H +#ifndef VOXEL_GIEDITORPLUGIN_H +#define VOXEL_GIEDITORPLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" -#include "scene/3d/gi_probe.h" +#include "scene/3d/voxel_gi.h" #include "scene/resources/material.h" -class GIProbeEditorPlugin : public EditorPlugin { - GDCLASS(GIProbeEditorPlugin, EditorPlugin); +class VoxelGIEditorPlugin : public EditorPlugin { + GDCLASS(VoxelGIEditorPlugin, EditorPlugin); - GIProbe *gi_probe; + VoxelGI *voxel_gi; HBoxContainer *bake_hb; Label *bake_info; @@ -54,21 +54,21 @@ class GIProbeEditorPlugin : public EditorPlugin { static void bake_func_end(); void _bake(); - void _giprobe_save_path_and_bake(const String &p_path); + void _voxel_gi_save_path_and_bake(const String &p_path); protected: static void _bind_methods(); void _notification(int p_what); public: - virtual String get_name() const override { return "GIProbe"; } + virtual String get_name() const override { return "VoxelGI"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override; - GIProbeEditorPlugin(EditorNode *p_node); - ~GIProbeEditorPlugin(); + VoxelGIEditorPlugin(EditorNode *p_node); + ~VoxelGIEditorPlugin(); }; -#endif // GIPROBEEDITORPLUGIN_H +#endif // VOXEL_GIEDITORPLUGIN_H diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 8bde397b5c..1b596ce599 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -2490,7 +2490,7 @@ ProjectManager::ProjectManager() { tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed)); HBoxContainer *projects_hb = memnew(HBoxContainer); - projects_hb->set_name(TTR("Projects")); + projects_hb->set_name(TTR("Local Projects")); tabs->add_child(projects_hb); { @@ -2621,7 +2621,7 @@ ProjectManager::ProjectManager() { version_btn = memnew(LinkButton); String hash = String(VERSION_HASH); if (hash.length() != 0) { - hash = "." + hash.left(9); + hash = " " + vformat("[%s]", hash.left(9)); } version_btn->set_text("v" VERSION_FULL_BUILD + hash); // Fade the version label to be less prominent, but still readable. @@ -2672,7 +2672,7 @@ ProjectManager::ProjectManager() { if (StreamPeerSSL::is_available()) { asset_library = memnew(EditorAssetLibrary(true)); - asset_library->set_name(TTR("Templates")); + asset_library->set_name(TTR("Asset Library Projects")); tabs->add_child(asset_library); asset_library->connect("install_asset", callable_mp(this, &ProjectManager::_install_project)); } else { diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 8b0d9ae0fc..7a4b0964fa 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -727,13 +727,13 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: value_editor[3]->set_text(String::num(plane.d)); } break; - case Variant::QUAT: { + case Variant::QUATERNION: { field_names.push_back("x"); field_names.push_back("y"); field_names.push_back("z"); field_names.push_back("w"); config_value_editors(4, 4, 10, field_names); - Quat q = v; + Quaternion q = v; value_editor[0]->set_text(String::num(q.x)); value_editor[1]->set_text(String::num(q.y)); value_editor[2]->set_text(String::num(q.z)); @@ -791,7 +791,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { field_names.push_back("xx"); field_names.push_back("xy"); field_names.push_back("xz"); @@ -806,7 +806,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: field_names.push_back("zo"); config_value_editors(12, 4, 16, field_names); - Transform tr = v; + Transform3D tr = v; for (int i = 0; i < 9; i++) { value_editor[(i / 3) * 4 + i % 3]->set_text(String::num(tr.basis.elements[i / 3][i % 3])); } @@ -1513,8 +1513,8 @@ void CustomPropertyEditor::_modified(String p_string) { _emit_changed_whole_or_field(); } break; - case Variant::QUAT: { - Quat q; + case Variant::QUATERNION: { + Quaternion q; q.x = _parse_real_expression(value_editor[0]->get_text()); q.y = _parse_real_expression(value_editor[1]->get_text()); q.z = _parse_real_expression(value_editor[2]->get_text()); @@ -1557,7 +1557,7 @@ void CustomPropertyEditor::_modified(String p_string) { _emit_changed_whole_or_field(); } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { Basis basis; for (int i = 0; i < 9; i++) { basis.elements[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text()); @@ -1569,7 +1569,7 @@ void CustomPropertyEditor::_modified(String p_string) { origin.y = _parse_real_expression(value_editor[7]->get_text()); origin.z = _parse_real_expression(value_editor[11]->get_text()); - v = Transform(basis, origin); + v = Transform3D(basis, origin); _emit_changed_whole_or_field(); } break; @@ -1635,11 +1635,11 @@ void CustomPropertyEditor::_focus_enter() { case Variant::RECT2: case Variant::VECTOR3: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::TRANSFORM2D: case Variant::BASIS: - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { for (int i = 0; i < MAX_VALUE_EDITORS; ++i) { if (value_editor[i]->has_focus()) { focused_value_editor = i; @@ -1661,11 +1661,11 @@ void CustomPropertyEditor::_focus_exit() { case Variant::RECT2: case Variant::VECTOR3: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::TRANSFORM2D: case Variant::BASIS: - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { for (int i = 0; i < MAX_VALUE_EDITORS; ++i) { value_editor[i]->select(0, 0); } diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index bf31be536c..d6db7a988f 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -125,18 +125,23 @@ void PropertySelector::_update_search() { search_options->get_theme_icon("float", "EditorIcons"), search_options->get_theme_icon("String", "EditorIcons"), search_options->get_theme_icon("Vector2", "EditorIcons"), + search_options->get_theme_icon("Vector2i", "EditorIcons"), search_options->get_theme_icon("Rect2", "EditorIcons"), + search_options->get_theme_icon("Rect2i", "EditorIcons"), search_options->get_theme_icon("Vector3", "EditorIcons"), + search_options->get_theme_icon("Vector3i", "EditorIcons"), search_options->get_theme_icon("Transform2D", "EditorIcons"), search_options->get_theme_icon("Plane", "EditorIcons"), - search_options->get_theme_icon("Quat", "EditorIcons"), + search_options->get_theme_icon("Quaternion", "EditorIcons"), search_options->get_theme_icon("AABB", "EditorIcons"), search_options->get_theme_icon("Basis", "EditorIcons"), search_options->get_theme_icon("Transform", "EditorIcons"), search_options->get_theme_icon("Color", "EditorIcons"), - search_options->get_theme_icon("Path", "EditorIcons"), + search_options->get_theme_icon("NodePath", "EditorIcons"), search_options->get_theme_icon("RID", "EditorIcons"), - search_options->get_theme_icon("Object", "EditorIcons"), + search_options->get_theme_icon("MiniObject", "EditorIcons"), + search_options->get_theme_icon("Callable", "EditorIcons"), + search_options->get_theme_icon("Signal", "EditorIcons"), search_options->get_theme_icon("Dictionary", "EditorIcons"), search_options->get_theme_icon("Array", "EditorIcons"), search_options->get_theme_icon("PackedByteArray", "EditorIcons"), diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 349e05b47b..8d6b7f3389 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2959,6 +2959,7 @@ void SceneTreeDock::_clear_clipboard() { void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) { List<PropertyInfo> props; p_node->get_property_list(&props); + bool is_instanced = EditorPropertyRevert::may_node_be_in_instance(p_node); for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { @@ -2969,6 +2970,15 @@ void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) if (v.is_ref()) { RES res = v; if (res.is_valid()) { + if (is_instanced) { + Variant orig; + if (EditorPropertyRevert::get_instanced_node_original_property(p_node, E->get().name, orig)) { + if (!EditorPropertyRevert::is_node_property_different(p_node, v, orig)) { + continue; + } + } + } + if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) { _create_remap_for_resource(res, r_remap); } diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 4cdf820877..c05a3c2f89 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -261,10 +261,6 @@ void EditorSettingsDialog::_update_shortcuts() { for (OrderedHashMap<StringName, InputMap::Action>::Element E = action_map.front(); E; E = E.next()) { String action_name = E.key(); - if (!shortcut_filter.is_subsequence_ofi(action_name)) { - continue; - } - InputMap::Action action = E.get(); Array events; // Need to get the list of events into an array so it can be set as metadata on the item. @@ -298,6 +294,10 @@ void EditorSettingsDialog::_update_shortcuts() { // Join the text of the events with a delimiter so they can all be displayed in one cell. String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings); + if (!shortcut_filter.is_subsequence_ofi(action_name) && (events_display_string == "None" || !shortcut_filter.is_subsequence_ofi(events_display_string))) { + continue; + } + TreeItem *item = shortcuts->create_item(common_section); item->set_text(0, action_name); item->set_text(1, events_display_string); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index ebef5be9ed..1893c6b6bb 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -199,7 +199,7 @@ protected: pinfo.type = Variant::TRANSFORM2D; } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - pinfo.type = Variant::TRANSFORM; + pinfo.type = Variant::TRANSFORM3D; } break; case RS::GLOBAL_VAR_TYPE_MAT4: { pinfo.type = Variant::PACKED_INT32_ARRAY; @@ -326,7 +326,7 @@ static Variant create_var(RS::GlobalVariableType p_type) { return Transform2D(); } case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - return Transform(); + return Transform3D(); } case RS::GLOBAL_VAR_TYPE_MAT4: { Vector<real_t> xform; diff --git a/misc/dist/linux/org.godotengine.Godot.xml b/misc/dist/linux/org.godotengine.Godot.xml index 2f647f71a6..e51179cd61 100644 --- a/misc/dist/linux/org.godotengine.Godot.xml +++ b/misc/dist/linux/org.godotengine.Godot.xml @@ -21,6 +21,12 @@ <glob pattern="*.escn"/> </mime-type> + <mime-type type="application/x-godot-shader"> + <comment>Godot Engine shader</comment> + <icon name="x-godot-shader" /> + <glob pattern="*.gdshader"/> + </mime-type> + <mime-type type="application/x-gdscript"> <comment>GDScript script</comment> <icon name="x-gdscript" /> diff --git a/misc/hooks/canonicalize_filename.sh b/misc/hooks/canonicalize_filename.sh index 5eecabf5bc..5fcae6ee70 100755 --- a/misc/hooks/canonicalize_filename.sh +++ b/misc/hooks/canonicalize_filename.sh @@ -13,7 +13,7 @@ # There should be no need to change anything below this line. # Canonicalize by recursively following every symlink in every component of the -# specified filename. This should reproduce the results of the GNU version of +# specified filename. This should reproduce the results of the GNU version of # readlink with the -f option. # # Reference: http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index 2dac8e9a55..81bc412944 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -76,7 +76,8 @@ fi # To get consistent formatting, we recommend contributors to use the same # clang-format version as CI. -RECOMMENDED_CLANG_FORMAT_MAJOR="11" +RECOMMENDED_CLANG_FORMAT_MAJOR_MIN="11" +RECOMMENDED_CLANG_FORMAT_MAJOR_MAX="12" if [ ! -x "$CLANG_FORMAT" ] ; then message="Error: clang-format executable not found. Please install clang-format $RECOMMENDED_CLANG_FORMAT_MAJOR.x.x." @@ -106,8 +107,8 @@ fi CLANG_FORMAT_VERSION="$(clang-format --version | sed "s/[^0-9\.]*\([0-9\.]*\).*/\1/")" CLANG_FORMAT_MAJOR="$(echo "$CLANG_FORMAT_VERSION" | cut -d. -f1)" -if [ "$CLANG_FORMAT_MAJOR" != "$RECOMMENDED_CLANG_FORMAT_MAJOR" ]; then - echo "Warning: Your clang-format binary is the wrong version ($CLANG_FORMAT_VERSION, expected $RECOMMENDED_CLANG_FORMAT_MAJOR.x.x)." +if [[ "$CLANG_FORMAT_MAJOR" -lt "$RECOMMENDED_CLANG_FORMAT_MAJOR_MIN" || "$CLANG_FORMAT_MAJOR" -gt "$RECOMMENDED_CLANG_FORMAT_MAJOR_MAX" ]]; then + echo "Warning: Your clang-format binary is the wrong version ($CLANG_FORMAT_VERSION, expected between $RECOMMENDED_CLANG_FORMAT_MAJOR_MIN.x.x and $RECOMMENDED_CLANG_FORMAT_MAJOR_MAX.x.x)." echo " Consider upgrading or downgrading clang-format as formatting may not be applied correctly." fi diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index e601884486..e07be14c5b 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -268,7 +268,7 @@ PhysicsServer3D::AreaSpaceOverrideMode BulletPhysicsServer3D::area_get_space_ove return area->get_spOv_mode(); } -void BulletPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { +void BulletPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -288,7 +288,7 @@ void BulletPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_sh area->set_shape(p_shape_idx, shape); } -void BulletPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) { +void BulletPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -309,9 +309,9 @@ RID BulletPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const { return area->get_shape(p_shape_idx)->get_self(); } -Transform BulletPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const { +Transform3D BulletPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const { AreaBullet *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, Transform()); + ERR_FAIL_COND_V(!area, Transform3D()); return area->get_shape_transform(p_shape_idx); } @@ -382,15 +382,15 @@ Variant BulletPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) } } -void BulletPhysicsServer3D::area_set_transform(RID p_area, const Transform &p_transform) { +void BulletPhysicsServer3D::area_set_transform(RID p_area, const Transform3D &p_transform) { AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); } -Transform BulletPhysicsServer3D::area_get_transform(RID p_area) const { +Transform3D BulletPhysicsServer3D::area_get_transform(RID p_area) const { AreaBullet *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, Transform()); + ERR_FAIL_COND_V(!area, Transform3D()); return area->get_transform(); } @@ -484,7 +484,7 @@ PhysicsServer3D::BodyMode BulletPhysicsServer3D::body_get_mode(RID p_body) const return body->get_mode(); } -void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { +void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -504,7 +504,7 @@ void BulletPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_sh body->set_shape(p_shape_idx, shape); } -void BulletPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) { +void BulletPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -527,9 +527,9 @@ RID BulletPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const { return shape->get_self(); } -Transform BulletPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const { +Transform3D BulletPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, Transform()); + ERR_FAIL_COND_V(!body, Transform3D()); return body->get_shape_transform(p_shape_idx); } @@ -842,7 +842,7 @@ PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_bod return BulletPhysicsDirectBodyState3D::get_singleton(body); } -bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { +bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -850,7 +850,7 @@ bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform &p_from return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes); } -int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { +int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); ERR_FAIL_COND_V(!body->get_space(), 0); @@ -990,7 +990,7 @@ Variant BulletPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state return Variant(); } -void BulletPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform &p_transform) { +void BulletPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -1205,7 +1205,7 @@ Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { return pin_joint->getPivotInB(); } -RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) { +RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); @@ -1277,7 +1277,7 @@ bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_f return hinge_joint->get_flag(p_flag); } -RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); @@ -1313,7 +1313,7 @@ real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointPar return slider_joint->get_param(p_param); } -RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); @@ -1347,7 +1347,7 @@ real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJ return coneTwist_joint->get_param(p_param); } -RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index de0379c873..d34d619ba2 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -134,12 +134,12 @@ public: virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) override; virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const override; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) override; + virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) override; - virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) override; + virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) override; virtual int area_get_shape_count(RID p_area) const override; virtual RID area_get_shape(RID p_area, int p_shape_idx) const override; - virtual Transform area_get_shape_transform(RID p_area, int p_shape_idx) const override; + virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const override; virtual void area_remove_shape(RID p_area, int p_shape_idx) override; virtual void area_clear_shapes(RID p_area) override; virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) override; @@ -153,8 +153,8 @@ public: virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) override; virtual Variant area_get_param(RID p_area, AreaParameter p_param) const override; - virtual void area_set_transform(RID p_area, const Transform &p_transform) override; - virtual Transform area_get_transform(RID p_area) const override; + virtual void area_set_transform(RID p_area, const Transform3D &p_transform) override; + virtual Transform3D area_get_transform(RID p_area) const override; virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; @@ -166,7 +166,7 @@ public: /* RIGID BODY API */ - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) override; + virtual RID body_create(BodyMode p_mode = BODY_MODE_DYNAMIC, bool p_init_sleeping = false) override; virtual void body_set_space(RID p_body, RID p_space) override; virtual RID body_get_space(RID p_body) const override; @@ -174,14 +174,14 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode) override; virtual BodyMode body_get_mode(RID p_body) const override; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) override; + virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; // Not supported, Please remove and add new shape virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override; - virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) override; + virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) override; virtual int body_get_shape_count(RID p_body) const override; virtual RID body_get_shape(RID p_body, int p_shape_idx) const override; - virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const override; + virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const override; virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override; @@ -253,8 +253,8 @@ public: // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; + virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; + virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; /* SOFT BODY API */ @@ -283,7 +283,7 @@ public: virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const override; /// Special function. This function has bad performance - virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) override; + virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override; virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override; @@ -333,7 +333,7 @@ public: virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) override; + virtual RID joint_create_hinge(RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) override; virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; @@ -343,19 +343,19 @@ public: virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; /// Reference frame is A - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual RID joint_create_slider(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; /// Reference frame is A - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual RID joint_create_cone_twist(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; /// Reference frame is A - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; + virtual RID joint_create_generic_6dof(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) override; virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override; diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp index 19d4816372..01461767bd 100644 --- a/modules/bullet/bullet_types_converter.cpp +++ b/modules/bullet/bullet_types_converter.cpp @@ -59,7 +59,7 @@ void INVERT_B_TO_G(btMatrix3x3 const &inVal, Basis &outVal) { INVERT_B_TO_G(inVal[2], outVal[2]); } -void B_TO_G(btTransform const &inVal, Transform &outVal) { +void B_TO_G(btTransform const &inVal, Transform3D &outVal) { B_TO_G(inVal.getBasis(), outVal.basis); B_TO_G(inVal.getOrigin(), outVal.origin); } @@ -89,7 +89,7 @@ void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal) { INVERT_G_TO_B(inVal[2], outVal[2]); } -void G_TO_B(Transform const &inVal, btTransform &outVal) { +void G_TO_B(Transform3D const &inVal, btTransform &outVal) { G_TO_B(inVal.basis, outVal.getBasis()); G_TO_B(inVal.origin, outVal.getOrigin()); } diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h index ca9b7175dd..e184fe1769 100644 --- a/modules/bullet/bullet_types_converter.h +++ b/modules/bullet/bullet_types_converter.h @@ -32,7 +32,7 @@ #define BULLET_TYPES_CONVERTER_H #include "core/math/basis.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector3.h" #include "core/typedefs.h" @@ -49,14 +49,14 @@ extern void B_TO_G(btVector3 const &inVal, Vector3 &outVal); extern void INVERT_B_TO_G(btVector3 const &inVal, Vector3 &outVal); extern void B_TO_G(btMatrix3x3 const &inVal, Basis &outVal); extern void INVERT_B_TO_G(btMatrix3x3 const &inVal, Basis &outVal); -extern void B_TO_G(btTransform const &inVal, Transform &outVal); +extern void B_TO_G(btTransform const &inVal, Transform3D &outVal); // Godot TO Bullet extern void G_TO_B(Vector3 const &inVal, btVector3 &outVal); extern void INVERT_G_TO_B(Vector3 const &inVal, btVector3 &outVal); extern void G_TO_B(Basis const &inVal, btMatrix3x3 &outVal); extern void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal); -extern void G_TO_B(Transform const &inVal, btTransform &outVal); +extern void G_TO_B(Transform3D const &inVal, btTransform &outVal); extern void UNSCALE_BT_BASIS(btTransform &scaledBasis); #endif diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index d9f5beb5a1..c45bd5bbc0 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -49,7 +49,7 @@ CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {} -void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_transform) { +void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform3D &p_transform) { G_TO_B(p_transform.get_basis().get_scale_abs(), scale); G_TO_B(p_transform, transform); UNSCALE_BT_BASIS(transform); @@ -193,7 +193,7 @@ int CollisionObjectBullet::get_godot_object_flags() const { return bt_collision_object->getUserIndex2(); } -void CollisionObjectBullet::set_transform(const Transform &p_global_transform) { +void CollisionObjectBullet::set_transform(const Transform3D &p_global_transform) { set_body_scale(p_global_transform.basis.get_scale_abs()); btTransform bt_transform; @@ -203,8 +203,8 @@ void CollisionObjectBullet::set_transform(const Transform &p_global_transform) { set_transform__bullet(bt_transform); } -Transform CollisionObjectBullet::get_transform() const { - Transform t; +Transform3D CollisionObjectBullet::get_transform() const { + Transform3D t; B_TO_G(get_transform__bullet(), t); t.basis.scale(body_scale); return t; @@ -230,7 +230,7 @@ RigidCollisionObjectBullet::~RigidCollisionObjectBullet() { } } -void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform, bool p_disabled) { +void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform3D &p_transform, bool p_disabled) { shapes.push_back(ShapeWrapper(p_shape, p_transform, !p_disabled)); p_shape->add_owner(this); reload_shapes(); @@ -296,7 +296,7 @@ void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBod } } -void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) { +void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform3D &p_transform) { ERR_FAIL_INDEX(p_index, get_shape_count()); shapes.write[p_index].set_transform(p_transform); @@ -307,8 +307,8 @@ const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_inde return shapes[p_index].transform; } -Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const { - Transform trs; +Transform3D RigidCollisionObjectBullet::get_shape_transform(int p_index) const { + Transform3D trs; B_TO_G(shapes[p_index].transform, trs); return trs; } diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index c8081a53f1..944ab89b87 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -31,7 +31,7 @@ #ifndef COLLISION_OBJECT_BULLET_H #define COLLISION_OBJECT_BULLET_H -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector3.h" #include "core/object/class_db.h" #include "core/templates/vset.h" @@ -83,7 +83,7 @@ public: set_transform(p_transform); } - ShapeWrapper(ShapeBullet *p_shape, const Transform &p_transform, bool p_active) : + ShapeWrapper(ShapeBullet *p_shape, const Transform3D &p_transform, bool p_active) : shape(p_shape), active(p_active) { set_transform(p_transform); @@ -102,7 +102,7 @@ public: active = otherShape.active; } - void set_transform(const Transform &p_transform); + void set_transform(const Transform3D &p_transform); void set_transform(const btTransform &p_transform); btTransform get_adjusted_transform() const; @@ -202,8 +202,8 @@ public: void set_godot_object_flags(int flags); int get_godot_object_flags() const; - void set_transform(const Transform &p_global_transform); - Transform get_transform() const; + void set_transform(const Transform3D &p_global_transform); + Transform3D get_transform() const; virtual void set_transform__bullet(const btTransform &p_global_transform); virtual const btTransform &get_transform__bullet() const; @@ -225,7 +225,7 @@ public: _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; } - void add_shape(ShapeBullet *p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); + void add_shape(ShapeBullet *p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false); void set_shape(int p_index, ShapeBullet *p_shape); int get_shape_count() const; @@ -238,10 +238,10 @@ public: void remove_shape_full(int p_index); void remove_all_shapes(bool p_permanentlyFromThisBody = false, bool p_force_not_reload = false); - void set_shape_transform(int p_index, const Transform &p_transform); + void set_shape_transform(int p_index, const Transform3D &p_transform); const btTransform &get_bt_shape_transform(int p_index) const; - Transform get_shape_transform(int p_index) const; + Transform3D get_shape_transform(int p_index) const; void set_shape_disabled(int p_index, bool p_disabled); bool is_shape_disabled(int p_index); diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp index e785780c5b..34516d8b3b 100644 --- a/modules/bullet/cone_twist_joint_bullet.cpp +++ b/modules/bullet/cone_twist_joint_bullet.cpp @@ -40,16 +40,16 @@ @author AndreaCatania */ -ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame) : +ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : JointBullet() { - Transform scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale())); + Transform3D scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale())); scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); btTransform btFrameA; G_TO_B(scaled_AFrame, btFrameA); if (rbB) { - Transform scaled_BFrame(rbBFrame.scaled(rbB->get_body_scale())); + Transform3D scaled_BFrame(rbBFrame.scaled(rbB->get_body_scale())); scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); btTransform btFrameB; diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h index 7d6bafd292..7e51f7d644 100644 --- a/modules/bullet/cone_twist_joint_bullet.h +++ b/modules/bullet/cone_twist_joint_bullet.h @@ -43,7 +43,7 @@ class ConeTwistJointBullet : public JointBullet { class btConeTwistConstraint *coneConstraint; public: - ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame); + ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame); virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; } diff --git a/modules/bullet/config.py b/modules/bullet/config.py index be7cf74f6f..83605f1f9b 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -1,6 +1,7 @@ def can_build(env, platform): # API Changed and bullet is disabled at the moment return False + # Later change to return not env["disable_3d"] def configure(env): diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp index 43ad6c56d5..7e04d57b9d 100644 --- a/modules/bullet/generic_6dof_joint_bullet.cpp +++ b/modules/bullet/generic_6dof_joint_bullet.cpp @@ -40,7 +40,7 @@ @author AndreaCatania */ -Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB) : +Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : JointBullet() { for (int i = 0; i < 3; i++) { for (int j = 0; j < PhysicsServer3D::G6DOF_JOINT_FLAG_MAX; j++) { @@ -48,7 +48,7 @@ Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBu } } - Transform scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); + Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); @@ -56,7 +56,7 @@ Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBu G_TO_B(scaled_AFrame, btFrameA); if (rbB) { - Transform scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); + Transform3D scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); @@ -71,30 +71,30 @@ Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBu setup(sixDOFConstraint); } -Transform Generic6DOFJointBullet::getFrameOffsetA() const { +Transform3D Generic6DOFJointBullet::getFrameOffsetA() const { btTransform btTrs = sixDOFConstraint->getFrameOffsetA(); - Transform gTrs; + Transform3D gTrs; B_TO_G(btTrs, gTrs); return gTrs; } -Transform Generic6DOFJointBullet::getFrameOffsetB() const { +Transform3D Generic6DOFJointBullet::getFrameOffsetB() const { btTransform btTrs = sixDOFConstraint->getFrameOffsetB(); - Transform gTrs; + Transform3D gTrs; B_TO_G(btTrs, gTrs); return gTrs; } -Transform Generic6DOFJointBullet::getFrameOffsetA() { +Transform3D Generic6DOFJointBullet::getFrameOffsetA() { btTransform btTrs = sixDOFConstraint->getFrameOffsetA(); - Transform gTrs; + Transform3D gTrs; B_TO_G(btTrs, gTrs); return gTrs; } -Transform Generic6DOFJointBullet::getFrameOffsetB() { +Transform3D Generic6DOFJointBullet::getFrameOffsetB() { btTransform btTrs = sixDOFConstraint->getFrameOffsetB(); - Transform gTrs; + Transform3D gTrs; B_TO_G(btTrs, gTrs); return gTrs; } diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h index 62b8e85a81..00567e3085 100644 --- a/modules/bullet/generic_6dof_joint_bullet.h +++ b/modules/bullet/generic_6dof_joint_bullet.h @@ -48,14 +48,14 @@ class Generic6DOFJointBullet : public JointBullet { bool flags[3][PhysicsServer3D::G6DOF_JOINT_FLAG_MAX]; public: - Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB); + Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB); virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; } - Transform getFrameOffsetA() const; - Transform getFrameOffsetB() const; - Transform getFrameOffsetA(); - Transform getFrameOffsetB(); + Transform3D getFrameOffsetA() const; + Transform3D getFrameOffsetB() const; + Transform3D getFrameOffsetA(); + Transform3D getFrameOffsetB(); void set_linear_lower_limit(const Vector3 &linearLower); void set_linear_upper_limit(const Vector3 &linearUpper); diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp index 4ceb98729f..b5fe50cf5f 100644 --- a/modules/bullet/hinge_joint_bullet.cpp +++ b/modules/bullet/hinge_joint_bullet.cpp @@ -40,16 +40,16 @@ @author AndreaCatania */ -HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB) : +HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB) : JointBullet() { - Transform scaled_AFrame(frameA.scaled(rbA->get_body_scale())); + Transform3D scaled_AFrame(frameA.scaled(rbA->get_body_scale())); scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); btTransform btFrameA; G_TO_B(scaled_AFrame, btFrameA); if (rbB) { - Transform scaled_BFrame(frameB.scaled(rbB->get_body_scale())); + Transform3D scaled_BFrame(frameB.scaled(rbB->get_body_scale())); scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); btTransform btFrameB; diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h index 06a95be374..dd0f69ba68 100644 --- a/modules/bullet/hinge_joint_bullet.h +++ b/modules/bullet/hinge_joint_bullet.h @@ -41,7 +41,7 @@ class HingeJointBullet : public JointBullet { class btHingeConstraint *hingeConstraint; public: - HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB); + HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB); HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 675da1a597..ce39d4f0df 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -106,11 +106,11 @@ Vector3 BulletPhysicsDirectBodyState3D::get_angular_velocity() const { return body->get_angular_velocity(); } -void BulletPhysicsDirectBodyState3D::set_transform(const Transform &p_transform) { +void BulletPhysicsDirectBodyState3D::set_transform(const Transform3D &p_transform) { body->set_transform(p_transform); } -Transform BulletPhysicsDirectBodyState3D::get_transform() const { +Transform3D BulletPhysicsDirectBodyState3D::get_transform() const { return body->get_transform(); } @@ -268,7 +268,7 @@ RigidBodyBullet::RigidBodyBullet() : reload_shapes(); setupBulletCollisionObject(btBody); - set_mode(PhysicsServer3D::BODY_MODE_RIGID); + set_mode(PhysicsServer3D::BODY_MODE_DYNAMIC); reload_axis_lock(); areasWhereIam.resize(maxAreasWhereIam); @@ -531,14 +531,14 @@ void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) { reload_axis_lock(); _internal_set_mass(0); break; - case PhysicsServer3D::BODY_MODE_RIGID: - mode = PhysicsServer3D::BODY_MODE_RIGID; + case PhysicsServer3D::BODY_MODE_DYNAMIC: + mode = PhysicsServer3D::BODY_MODE_DYNAMIC; reload_axis_lock(); _internal_set_mass(0 == mass ? 1 : mass); scratch_space_override_modificator(); break; - case PhysicsServer3D::BODY_MODE_CHARACTER: - mode = PhysicsServer3D::BODY_MODE_CHARACTER; + case PhysicsServer3D::MODE_DYNAMIC_LOCKED: + mode = PhysicsServer3D::MODE_DYNAMIC_LOCKED; reload_axis_lock(); _internal_set_mass(0 == mass ? 1 : mass); scratch_space_override_modificator(); @@ -711,7 +711,7 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { void RigidBodyBullet::reload_axis_lock() { btBody->setLinearFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)))); - if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) { + if (PhysicsServer3D::MODE_DYNAMIC_LOCKED == mode) { /// When character angular is always locked btBody->setAngularFactor(btVector3(0., 0., 0.)); } else { @@ -1006,7 +1006,7 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) { // Rigidbody is dynamic if and only if mass is non Zero, otherwise static const bool isDynamic = p_mass != 0.f; if (isDynamic) { - if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode) { + if (PhysicsServer3D::BODY_MODE_DYNAMIC != mode && PhysicsServer3D::MODE_DYNAMIC_LOCKED != mode) { return; } @@ -1015,7 +1015,7 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) { mainShape->calculateLocalInertia(p_mass, localInertia); } - if (PhysicsServer3D::BODY_MODE_RIGID == mode) { + if (PhysicsServer3D::BODY_MODE_DYNAMIC == mode) { btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static } else { btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_CHARACTER_OBJECT); diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 843ff4a7af..606df7134b 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -107,8 +107,8 @@ public: virtual void set_angular_velocity(const Vector3 &p_velocity) override; virtual Vector3 get_angular_velocity() const override; - virtual void set_transform(const Transform &p_transform) override; - virtual Transform get_transform() const override; + virtual void set_transform(const Transform3D &p_transform) override; + virtual Transform3D get_transform() const override; virtual void add_central_force(const Vector3 &p_force) override; virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override; diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp index 45c892851b..1d83118468 100644 --- a/modules/bullet/slider_joint_bullet.cpp +++ b/modules/bullet/slider_joint_bullet.cpp @@ -40,16 +40,16 @@ @author AndreaCatania */ -SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB) : +SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : JointBullet() { - Transform scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); + Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale())); scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis); btTransform btFrameA; G_TO_B(scaled_AFrame, btFrameA); if (rbB) { - Transform scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); + Transform3D scaled_BFrame(frameInB.scaled(rbB->get_body_scale())); scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis); btTransform btFrameB; @@ -70,44 +70,44 @@ const RigidBodyBullet *SliderJointBullet::getRigidBodyB() const { return static_cast<RigidBodyBullet *>(sliderConstraint->getRigidBodyB().getUserPointer()); } -const Transform SliderJointBullet::getCalculatedTransformA() const { +const Transform3D SliderJointBullet::getCalculatedTransformA() const { btTransform btTransform = sliderConstraint->getCalculatedTransformA(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } -const Transform SliderJointBullet::getCalculatedTransformB() const { +const Transform3D SliderJointBullet::getCalculatedTransformB() const { btTransform btTransform = sliderConstraint->getCalculatedTransformB(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } -const Transform SliderJointBullet::getFrameOffsetA() const { +const Transform3D SliderJointBullet::getFrameOffsetA() const { btTransform btTransform = sliderConstraint->getFrameOffsetA(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } -const Transform SliderJointBullet::getFrameOffsetB() const { +const Transform3D SliderJointBullet::getFrameOffsetB() const { btTransform btTransform = sliderConstraint->getFrameOffsetB(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } -Transform SliderJointBullet::getFrameOffsetA() { +Transform3D SliderJointBullet::getFrameOffsetA() { btTransform btTransform = sliderConstraint->getFrameOffsetA(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } -Transform SliderJointBullet::getFrameOffsetB() { +Transform3D SliderJointBullet::getFrameOffsetB() { btTransform btTransform = sliderConstraint->getFrameOffsetB(); - Transform gTrans; + Transform3D gTrans; B_TO_G(btTransform, gTrans); return gTrans; } diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h index 90964671c2..0c93558449 100644 --- a/modules/bullet/slider_joint_bullet.h +++ b/modules/bullet/slider_joint_bullet.h @@ -44,18 +44,18 @@ class SliderJointBullet : public JointBullet { public: /// Reference frame is A - SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB); + SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB); virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; } const RigidBodyBullet *getRigidBodyA() const; const RigidBodyBullet *getRigidBodyB() const; - const Transform getCalculatedTransformA() const; - const Transform getCalculatedTransformB() const; - const Transform getFrameOffsetA() const; - const Transform getFrameOffsetB() const; - Transform getFrameOffsetA(); - Transform getFrameOffsetB(); + const Transform3D getCalculatedTransformA() const; + const Transform3D getCalculatedTransformB() const; + const Transform3D getFrameOffsetA() const; + const Transform3D getFrameOffsetB() const; + Transform3D getFrameOffsetA(); + Transform3D getFrameOffsetB(); real_t getLowerLinLimit() const; void setLowerLinLimit(real_t lowerLimit); real_t getUpperLinLimit() const; diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 2c8727baf2..bbbb0e7851 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -136,7 +136,7 @@ void SoftBodyBullet::destroy_soft_body() { bt_soft_body = nullptr; } -void SoftBodyBullet::set_soft_transform(const Transform &p_transform) { +void SoftBodyBullet::set_soft_transform(const Transform3D &p_transform) { reset_all_node_positions(); move_all_nodes(p_transform); } @@ -159,7 +159,7 @@ AABB SoftBodyBullet::get_bounds() const { return aabb; } -void SoftBodyBullet::move_all_nodes(const Transform &p_transform) { +void SoftBodyBullet::move_all_nodes(const Transform3D &p_transform) { if (!bt_soft_body) { return; } diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index 87023b2517..63708b57a7 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -104,11 +104,11 @@ public: void destroy_soft_body(); // Special function. This function has bad performance - void set_soft_transform(const Transform &p_transform); + void set_soft_transform(const Transform3D &p_transform); AABB get_bounds() const; - void move_all_nodes(const Transform &p_transform); + void move_all_nodes(const Transform3D &p_transform); void set_node_position(int node_index, const Vector3 &p_global_position); void set_node_position(int node_index, const btVector3 &p_global_position); void get_node_position(int node_index, Vector3 &r_position) const; diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index bdaec4a09e..33dd9ef56d 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -117,7 +117,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V } } -int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return 0; } @@ -152,7 +152,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { +bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { r_closest_safe = 0.0f; r_closest_unsafe = 0.0f; btVector3 bt_motion; @@ -214,7 +214,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf } /// Returns the list of contacts pairs in this order: Local contact, other body contact -bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return false; } @@ -250,7 +250,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & return btQuery.m_count; } -bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -445,7 +445,7 @@ real_t SpaceBullet::get_param(PhysicsServer3D::SpaceParameter p_param) { case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: default: - WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); + WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); return 0.f; } } @@ -908,7 +908,7 @@ static Ref<StandardMaterial3D> red_mat; static Ref<StandardMaterial3D> blue_mat; #endif -bool SpaceBullet::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) { +bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) { #if debug_test_motion /// Yes I know this is not good, but I've used it as fast debugging hack. /// I'm leaving it here just for speedup the other eventual debugs @@ -1062,7 +1062,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f return has_penetration; } -int SpaceBullet::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, real_t p_margin) { +int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) { btTransform body_transform; G_TO_B(p_transform, body_transform); UNSCALE_BT_BASIS(body_transform); diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 87aa2b9e93..36d0538e6b 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -78,11 +78,11 @@ public: virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; + virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; /// Returns the list of contacts pairs in this order: Local contact, other body contact - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; }; @@ -188,8 +188,8 @@ public: 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, real_t p_margin); + bool test_body_motion(RigidBodyBullet *p_body, const Transform3D &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 Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin); private: void create_empty_world(bool p_create_soft_world); diff --git a/modules/csg/config.py b/modules/csg/config.py index 9106cbceca..3991b846f9 100644 --- a/modules/csg/config.py +++ b/modules/csg/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 7387842259..5a37486568 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -265,7 +265,7 @@ void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector< _regen_face_aabbs(); } -void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) { +void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform3D &p_xform) { faces = p_brush.faces; materials = p_brush.materials; diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 3fbed66e5c..4bd79e15a9 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -33,7 +33,7 @@ #include "core/math/aabb.h" #include "core/math/plane.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/math/vector3.h" #include "core/object/reference.h" @@ -60,7 +60,7 @@ struct CSGBrush { // Create a brush from faces. void build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces); - void copy_from(const CSGBrush &p_brush, const Transform &p_xform); + void copy_from(const CSGBrush &p_brush, const Transform3D &p_xform); }; struct CSGBrushOperation { @@ -165,8 +165,8 @@ struct CSGBrushOperation { Vector<Vertex2D> vertices; Vector<Face2D> faces; Plane plane; - Transform to_2D; - Transform to_3D; + Transform3D to_2D; + Transform3D to_3D; float vertex_snap2 = 0.0; inline int _get_point_idx(const Vector2 &p_point); diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 8a46dcca65..37a7d96de5 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -99,9 +99,9 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node()); - Transform gt = cs->get_global_transform(); + Transform3D gt = cs->get_global_transform(); //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); + Transform3D gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 67dfdfb5eb..d6690bb96c 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -578,7 +578,7 @@ Array CSGShape3D::get_meshes() const { if (root_mesh.is_valid()) { Array arr; arr.resize(2); - arr[0] = Transform(); + arr[0] = Transform3D(); arr[1] = root_mesh; return arr; } @@ -1978,13 +1978,13 @@ CSGBrush *CSGPolygon3D::_build_brush() { float u1 = 0.0; float u2 = path_continuous_u ? 0.0 : 1.0; - Transform path_to_this; + Transform3D path_to_this; if (!path_local) { // center on paths origin path_to_this = get_global_transform().affine_inverse() * path->get_global_transform(); } - Transform prev_xf; + Transform3D prev_xf; Vector3 lookat_dir; @@ -2006,7 +2006,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { ofs = 0.0; } - Transform xf; + Transform3D xf; xf.origin = curve->interpolate_baked(ofs); Vector3 local_dir; diff --git a/modules/csg/doc_classes/CSGShape3D.xml b/modules/csg/doc_classes/CSGShape3D.xml index dac556c7f1..01ec46e707 100644 --- a/modules/csg/doc_classes/CSGShape3D.xml +++ b/modules/csg/doc_classes/CSGShape3D.xml @@ -31,7 +31,7 @@ <return type="Array"> </return> <description> - Returns an [Array] with two elements, the first is the [Transform] of this node and the second is the root [Mesh] of this node. Only works when this node is the root shape. + Returns an [Array] with two elements, the first is the [Transform3D] of this node and the second is the root [Mesh] of this node. Only works when this node is the root shape. </description> </method> <method name="is_root_shape" qualifiers="const"> diff --git a/modules/fbx/README.md b/modules/fbx/README.md index 69a50d4bea..8eca4bd3c9 100644 --- a/modules/fbx/README.md +++ b/modules/fbx/README.md @@ -79,23 +79,23 @@ enum RotOrder { // references: ComputePivotTransform / run the calculation // This is the local pivot transform for the node, not the global transforms Transform ComputePivotTransform( - Transform chain[TransformationComp_MAXIMUM], - Transform &geometric_transform) { + Transform3D chain[TransformationComp_MAXIMUM], + Transform3D &geometric_transform) { // Maya pivots - Transform T = chain[TransformationComp_Translation]; - Transform Roff = chain[TransformationComp_RotationOffset]; - Transform Rp = chain[TransformationComp_RotationPivot]; - Transform Rpre = chain[TransformationComp_PreRotation]; - Transform R = chain[TransformationComp_Rotation]; - Transform Rpost = chain[TransformationComp_PostRotation]; - Transform Soff = chain[TransformationComp_ScalingOffset]; - Transform Sp = chain[TransformationComp_ScalingPivot]; - Transform S = chain[TransformationComp_Scaling]; + Transform3D T = chain[TransformationComp_Translation]; + Transform3D Roff = chain[TransformationComp_RotationOffset]; + Transform3D Rp = chain[TransformationComp_RotationPivot]; + Transform3D Rpre = chain[TransformationComp_PreRotation]; + Transform3D R = chain[TransformationComp_Rotation]; + Transform3D Rpost = chain[TransformationComp_PostRotation]; + Transform3D Soff = chain[TransformationComp_ScalingOffset]; + Transform3D Sp = chain[TransformationComp_ScalingPivot]; + Transform3D S = chain[TransformationComp_Scaling]; // 3DS Max Pivots - Transform OT = chain[TransformationComp_GeometricTranslation]; - Transform OR = chain[TransformationComp_GeometricRotation]; - Transform OS = chain[TransformationComp_GeometricScaling]; + Transform3D OT = chain[TransformationComp_GeometricTranslation]; + Transform3D OR = chain[TransformationComp_GeometricRotation]; + Transform3D OS = chain[TransformationComp_GeometricScaling]; // Calculate 3DS max pivot transform - use geometric space (e.g doesn't effect children nodes only the current node) geometric_transform = OT * OR * OS; diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index 349bcaeeaa..8f32c523f9 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -1126,8 +1126,8 @@ HashMap<int, R> FBXMeshData::extract_per_vertex_data( } const int vertex_index = get_vertex_from_polygon_vertex(p_mesh_indices, polygon_vertex_index); ERR_FAIL_COND_V_MSG(vertex_index < 0, (HashMap<int, R>()), "FBX file corrupted: #ERR8"); - ERR_FAIL_COND_V_MSG(vertex_index >= p_vertex_count, (HashMap<int, R>()), "FBX file seems corrupted: #ERR9."); - ERR_FAIL_COND_V_MSG(p_mapping_data.index[polygon_vertex_index] < 0, (HashMap<int, R>()), "FBX file seems corrupted: #ERR10."); + ERR_FAIL_COND_V_MSG(vertex_index >= p_vertex_count, (HashMap<int, R>()), "FBX file seems corrupted: #ERR9."); + ERR_FAIL_COND_V_MSG(p_mapping_data.index[polygon_vertex_index] < 0, (HashMap<int, R>()), "FBX file seems corrupted: #ERR10."); ERR_FAIL_COND_V_MSG(p_mapping_data.index[polygon_vertex_index] >= (int)p_mapping_data.data.size(), (HashMap<int, R>()), "FBX file seems corrupted: #ERR11."); aggregate_vertex_data[vertex_index].push_back({ polygon_id, p_mapping_data.data[p_mapping_data.index[polygon_vertex_index]] }); } diff --git a/modules/fbx/data/pivot_transform.cpp b/modules/fbx/data/pivot_transform.cpp index f4055c830f..4cf42257a4 100644 --- a/modules/fbx/data/pivot_transform.cpp +++ b/modules/fbx/data/pivot_transform.cpp @@ -90,7 +90,7 @@ void PivotTransform::ReadTransformChain() { if (ok) { geometric_rotation = ImportUtils::EulerToQuaternion(rot, ImportUtils::deg2rad(GeometricRotation)); } else { - geometric_rotation = Quat(); + geometric_rotation = Quaternion(); } const Vector3 &GeometricTranslation = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "GeometricTranslation", ok)); @@ -100,7 +100,7 @@ void PivotTransform::ReadTransformChain() { geometric_translation = Vector3(0, 0, 0); } - if (geometric_rotation != Quat()) { + if (geometric_rotation != Quaternion()) { print_error("geometric rotation is unsupported!"); //CRASH_COND(true); } @@ -116,8 +116,8 @@ void PivotTransform::ReadTransformChain() { } } -Transform PivotTransform::ComputeLocalTransform(Vector3 p_translation, Quat p_rotation, Vector3 p_scaling) const { - Transform T, Roff, Rp, Soff, Sp, S; +Transform3D PivotTransform::ComputeLocalTransform(Vector3 p_translation, Quaternion p_rotation, Vector3 p_scaling) const { + Transform3D T, Roff, Rp, Soff, Sp, S; // Here I assume this is the operation which needs done. // Its WorldTransform * V @@ -132,29 +132,29 @@ Transform PivotTransform::ComputeLocalTransform(Vector3 p_translation, Quat p_ro // Scaling node S.scale(p_scaling); // Rotation pivots - Transform Rpre = Transform(pre_rotation); - Transform R = Transform(p_rotation); - Transform Rpost = Transform(post_rotation); + Transform3D Rpre = Transform3D(pre_rotation); + Transform3D R = Transform3D(p_rotation); + Transform3D Rpost = Transform3D(post_rotation); return T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse(); } -Transform PivotTransform::ComputeGlobalTransform(Transform t) const { +Transform3D PivotTransform::ComputeGlobalTransform(Transform3D t) const { Vector3 pos = t.origin; Vector3 scale = t.basis.get_scale(); - Quat rot = t.basis.get_rotation_quat(); + Quaternion rot = t.basis.get_rotation_quaternion(); return ComputeGlobalTransform(pos, rot, scale); } -Transform PivotTransform::ComputeLocalTransform(Transform t) const { +Transform3D PivotTransform::ComputeLocalTransform(Transform3D t) const { Vector3 pos = t.origin; Vector3 scale = t.basis.get_scale(); - Quat rot = t.basis.get_rotation_quat(); + Quaternion rot = t.basis.get_rotation_quaternion(); return ComputeLocalTransform(pos, rot, scale); } -Transform PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quat p_rotation, Vector3 p_scaling) const { - Transform T, Roff, Rp, Soff, Sp, S; +Transform3D PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quaternion p_rotation, Vector3 p_scaling) const { + Transform3D T, Roff, Rp, Soff, Sp, S; // Here I assume this is the operation which needs done. // Its WorldTransform * V @@ -170,26 +170,26 @@ Transform PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quat p_r S.scale(p_scaling); // Rotation pivots - Transform Rpre = Transform(pre_rotation); - Transform R = Transform(p_rotation); - Transform Rpost = Transform(post_rotation); + Transform3D Rpre = Transform3D(pre_rotation); + Transform3D R = Transform3D(p_rotation); + Transform3D Rpost = Transform3D(post_rotation); - Transform parent_global_xform; - Transform parent_local_scaling_m; + Transform3D parent_global_xform; + Transform3D parent_local_scaling_m; if (parent_transform.is_valid()) { parent_global_xform = parent_transform->GlobalTransform; parent_local_scaling_m = parent_transform->Local_Scaling_Matrix; } - Transform local_rotation_m, parent_global_rotation_m; - Quat parent_global_rotation = parent_global_xform.basis.get_rotation_quat(); - parent_global_rotation_m.basis.set_quat(parent_global_rotation); + Transform3D local_rotation_m, parent_global_rotation_m; + Quaternion parent_global_rotation = parent_global_xform.basis.get_rotation_quaternion(); + parent_global_rotation_m.basis.set_quaternion(parent_global_rotation); local_rotation_m = Rpre * R * Rpost; - //Basis parent_global_rotation = Basis(parent_global_xform.get_basis().get_rotation_quat().normalized()); + //Basis parent_global_rotation = Basis(parent_global_xform.get_basis().get_rotation_quaternion().normalized()); - Transform local_shear_scaling, parent_shear_scaling, parent_shear_rotation, parent_shear_translation; + Transform3D local_shear_scaling, parent_shear_scaling, parent_shear_rotation, parent_shear_translation; Vector3 parent_translation = parent_global_xform.get_origin(); parent_shear_translation.origin = parent_translation; parent_shear_rotation = parent_shear_translation.affine_inverse() * parent_global_xform; @@ -197,26 +197,26 @@ Transform PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quat p_r local_shear_scaling = S; // Inherit type handler - we don't care about T here, just reordering RSrs etc. - Transform global_rotation_scale; + Transform3D global_rotation_scale; if (inherit_type == FBXDocParser::Transform_RrSs) { global_rotation_scale = parent_global_rotation_m * local_rotation_m * parent_shear_scaling * local_shear_scaling; } else if (inherit_type == FBXDocParser::Transform_RSrs) { global_rotation_scale = parent_global_rotation_m * parent_shear_scaling * local_rotation_m * local_shear_scaling; } else if (inherit_type == FBXDocParser::Transform_Rrs) { - Transform parent_global_shear_m_noLocal = parent_shear_scaling * parent_local_scaling_m.affine_inverse(); + Transform3D parent_global_shear_m_noLocal = parent_shear_scaling * parent_local_scaling_m.affine_inverse(); global_rotation_scale = parent_global_rotation_m * local_rotation_m * parent_global_shear_m_noLocal * local_shear_scaling; } - Transform local_transform = T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse(); - //Transform local_translation_pivoted = Transform(Basis(), LocalTransform.origin); + Transform3D local_transform = T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse(); + //Transform3D local_translation_pivoted = Transform3D(Basis(), LocalTransform.origin); - ERR_FAIL_COND_V_MSG(local_transform.basis.determinant() == 0, Transform(), "Det == 0 prevented in scene file"); + ERR_FAIL_COND_V_MSG(local_transform.basis.determinant() == 0, Transform3D(), "Det == 0 prevented in scene file"); // manual hack to force SSC not to be compensated for - until we can handle it properly with tests return parent_global_xform * local_transform; } void PivotTransform::ComputePivotTransform() { - Transform T, Roff, Rp, Soff, Sp, S; + Transform3D T, Roff, Rp, Soff, Sp, S; // Here I assume this is the operation which needs done. // Its WorldTransform * V @@ -237,26 +237,26 @@ void PivotTransform::ComputePivotTransform() { Local_Scaling_Matrix = S; // copy for when node / child is looking for the value of this. // Rotation pivots - Transform Rpre = Transform(pre_rotation); - Transform R = Transform(rotation); - Transform Rpost = Transform(post_rotation); + Transform3D Rpre = Transform3D(pre_rotation); + Transform3D R = Transform3D(rotation); + Transform3D Rpost = Transform3D(post_rotation); - Transform parent_global_xform; - Transform parent_local_scaling_m; + Transform3D parent_global_xform; + Transform3D parent_local_scaling_m; if (parent_transform.is_valid()) { parent_global_xform = parent_transform->GlobalTransform; parent_local_scaling_m = parent_transform->Local_Scaling_Matrix; } - Transform local_rotation_m, parent_global_rotation_m; - Quat parent_global_rotation = parent_global_xform.basis.get_rotation_quat(); - parent_global_rotation_m.basis.set_quat(parent_global_rotation); + Transform3D local_rotation_m, parent_global_rotation_m; + Quaternion parent_global_rotation = parent_global_xform.basis.get_rotation_quaternion(); + parent_global_rotation_m.basis.set_quaternion(parent_global_rotation); local_rotation_m = Rpre * R * Rpost; - //Basis parent_global_rotation = Basis(parent_global_xform.get_basis().get_rotation_quat().normalized()); + //Basis parent_global_rotation = Basis(parent_global_xform.get_basis().get_rotation_quaternion().normalized()); - Transform local_shear_scaling, parent_shear_scaling, parent_shear_rotation, parent_shear_translation; + Transform3D local_shear_scaling, parent_shear_scaling, parent_shear_rotation, parent_shear_translation; Vector3 parent_translation = parent_global_xform.get_origin(); parent_shear_translation.origin = parent_translation; parent_shear_rotation = parent_shear_translation.affine_inverse() * parent_global_xform; @@ -264,24 +264,24 @@ void PivotTransform::ComputePivotTransform() { local_shear_scaling = S; // Inherit type handler - we don't care about T here, just reordering RSrs etc. - Transform global_rotation_scale; + Transform3D global_rotation_scale; if (inherit_type == FBXDocParser::Transform_RrSs) { global_rotation_scale = parent_global_rotation_m * local_rotation_m * parent_shear_scaling * local_shear_scaling; } else if (inherit_type == FBXDocParser::Transform_RSrs) { global_rotation_scale = parent_global_rotation_m * parent_shear_scaling * local_rotation_m * local_shear_scaling; } else if (inherit_type == FBXDocParser::Transform_Rrs) { - Transform parent_global_shear_m_noLocal = parent_shear_scaling * parent_local_scaling_m.inverse(); + Transform3D parent_global_shear_m_noLocal = parent_shear_scaling * parent_local_scaling_m.inverse(); global_rotation_scale = parent_global_rotation_m * local_rotation_m * parent_global_shear_m_noLocal * local_shear_scaling; } - LocalTransform = Transform(); + LocalTransform = Transform3D(); LocalTransform = T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse(); ERR_FAIL_COND_MSG(LocalTransform.basis.determinant() == 0, "invalid scale reset"); - Transform local_translation_pivoted = Transform(Basis(), LocalTransform.origin); - GlobalTransform = Transform(); + Transform3D local_translation_pivoted = Transform3D(Basis(), LocalTransform.origin); + GlobalTransform = Transform3D(); //GlobalTransform = parent_global_xform * LocalTransform; - Transform global_origin = Transform(Basis(), parent_translation); + Transform3D global_origin = Transform3D(Basis(), parent_translation); GlobalTransform = (global_origin * local_translation_pivoted) * global_rotation_scale; ImportUtils::debug_xform("local xform calculation", LocalTransform); diff --git a/modules/fbx/data/pivot_transform.h b/modules/fbx/data/pivot_transform.h index 9996027870..29cf7a3d0e 100644 --- a/modules/fbx/data/pivot_transform.h +++ b/modules/fbx/data/pivot_transform.h @@ -31,7 +31,7 @@ #ifndef PIVOT_TRANSFORM_H #define PIVOT_TRANSFORM_H -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/object/reference.h" #include "model_abstraction.h" @@ -58,10 +58,10 @@ enum TransformationComp { struct PivotTransform : Reference, ModelAbstraction { // at the end we want to keep geometric_ everything, post and pre rotation // these are used during animation data processing / keyframe ingestion the rest can be simplified down / out. - Quat pre_rotation = Quat(); - Quat post_rotation = Quat(); - Quat rotation = Quat(); - Quat geometric_rotation = Quat(); + Quaternion pre_rotation = Quaternion(); + Quaternion post_rotation = Quaternion(); + Quaternion rotation = Quaternion(); + Quaternion geometric_rotation = Quaternion(); Vector3 rotation_pivot = Vector3(); Vector3 rotation_offset = Vector3(); Vector3 scaling_offset = Vector3(1.0, 1.0, 1.0); @@ -85,10 +85,10 @@ struct PivotTransform : Reference, ModelAbstraction { print_verbose("raw post_rotation " + raw_post_rotation * (180 / Math_PI)); } - Transform ComputeGlobalTransform(Transform t) const; - Transform ComputeLocalTransform(Transform t) const; - Transform ComputeGlobalTransform(Vector3 p_translation, Quat p_rotation, Vector3 p_scaling) const; - Transform ComputeLocalTransform(Vector3 p_translation, Quat p_rotation, Vector3 p_scaling) const; + Transform3D ComputeGlobalTransform(Transform3D t) const; + Transform3D ComputeLocalTransform(Transform3D t) const; + Transform3D ComputeGlobalTransform(Vector3 p_translation, Quaternion p_rotation, Vector3 p_scaling) const; + Transform3D ComputeLocalTransform(Vector3 p_translation, Quaternion p_rotation, Vector3 p_scaling) const; /* Extract into xforms and calculate once */ void ComputePivotTransform(); @@ -105,10 +105,10 @@ struct PivotTransform : Reference, ModelAbstraction { //Transform chain[TransformationComp_MAXIMUM]; // cached for later use - Transform GlobalTransform = Transform(); - Transform LocalTransform = Transform(); - Transform Local_Scaling_Matrix = Transform(); // used for inherit type. - Transform GeometricTransform = Transform(); // 3DS max only + Transform3D GlobalTransform = Transform3D(); + Transform3D LocalTransform = Transform3D(); + Transform3D Local_Scaling_Matrix = Transform3D(); // used for inherit type. + Transform3D GeometricTransform = Transform3D(); // 3DS max only FBXDocParser::TransformInheritance inherit_type = FBXDocParser::TransformInheritance_MAX; // maya fbx requires this - sorry <3 }; diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index f60277f60a..40deaae74d 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -258,24 +258,24 @@ struct EditorSceneImporterAssetImportInterpolate { //thank you for existing, partial specialization template <> -struct EditorSceneImporterAssetImportInterpolate<Quat> { - Quat lerp(const Quat &a, const Quat &b, float c) const { - ERR_FAIL_COND_V(!a.is_normalized(), Quat()); - ERR_FAIL_COND_V(!b.is_normalized(), Quat()); +struct EditorSceneImporterAssetImportInterpolate<Quaternion> { + Quaternion lerp(const Quaternion &a, const Quaternion &b, float c) const { + ERR_FAIL_COND_V(!a.is_normalized(), Quaternion()); + ERR_FAIL_COND_V(!b.is_normalized(), Quaternion()); return a.slerp(b, c).normalized(); } - Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) { - ERR_FAIL_COND_V(!p1.is_normalized(), Quat()); - ERR_FAIL_COND_V(!p2.is_normalized(), Quat()); + Quaternion catmull_rom(const Quaternion &p0, const Quaternion &p1, const Quaternion &p2, const Quaternion &p3, float c) { + ERR_FAIL_COND_V(!p1.is_normalized(), Quaternion()); + ERR_FAIL_COND_V(!p2.is_normalized(), Quaternion()); return p1.slerp(p2, c).normalized(); } - Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) { - ERR_FAIL_COND_V(!start.is_normalized(), Quat()); - ERR_FAIL_COND_V(!end.is_normalized(), Quat()); + Quaternion bezier(Quaternion start, Quaternion control_1, Quaternion control_2, Quaternion end, float t) { + ERR_FAIL_COND_V(!start.is_normalized(), Quaternion()); + ERR_FAIL_COND_V(!end.is_normalized(), Quaternion()); return start.slerp(end, t).normalized(); } @@ -888,7 +888,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // we need to know what object the curves are for. // we need the target ID and the target name for the track reduction. - FBXDocParser::Model::RotOrder quat_rotation_order = FBXDocParser::Model::RotOrder_EulerXYZ; + FBXDocParser::Model::RotOrder quaternion_rotation_order = FBXDocParser::Model::RotOrder_EulerXYZ; // T:: R:: S:: Visible:: Custom:: for (const FBXDocParser::AnimationCurveNode *curve_node : node_list) { @@ -910,7 +910,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( continue; } else { //print_verbose("[doc] applied rotation order: " + itos(target->RotationOrder())); - quat_rotation_order = target->RotationOrder(); + quaternion_rotation_order = target->RotationOrder(); } uint64_t target_id = target->ID(); @@ -1011,7 +1011,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // track count is 5. // next track id is 5. const uint64_t target_id = track->key(); - int track_idx = animation->add_track(Animation::TYPE_TRANSFORM); + int track_idx = animation->add_track(Animation::TYPE_TRANSFORM3D); // animation->track_set_path(track_idx, node_path); Ref<FBXBone> bone; @@ -1023,7 +1023,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( bone = state.fbx_bone_map[target_id]; } - Transform target_transform; + Transform3D target_transform; if (state.fbx_target_map.has(target_id)) { Ref<FBXNode> node_ref = state.fbx_target_map[target_id]; @@ -1086,7 +1086,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( Vector<float> pos_times; Vector<Vector3> scale_values; Vector<float> scale_times; - Vector<Quat> rot_values; + Vector<Quaternion> rot_values; Vector<float> rot_times; double max_duration = 0; @@ -1122,8 +1122,8 @@ Node3D *EditorSceneImporterFBX::_generate_scene( bool got_pre = false; bool got_post = false; - Quat post_rotation; - Quat pre_rotation; + Quaternion post_rotation; + Quaternion pre_rotation; // Rotation matrix const Vector3 &PreRotation = FBXDocParser::PropertyGet<Vector3>(props, "PreRotation", got_pre); @@ -1137,24 +1137,24 @@ Node3D *EditorSceneImporterFBX::_generate_scene( post_rotation = ImportUtils::EulerToQuaternion(rot_order, ImportUtils::deg2rad(PostRotation)); } - Quat lastQuat = Quat(); + Quaternion lastQuaternion = Quaternion(); for (std::pair<int64_t, Vector3> rotation_key : rotation_keys.keyframes) { double animation_track_time = CONVERT_FBX_TIME(rotation_key.first); //print_verbose("euler rotation key: " + rotation_key.second); - Quat rot_key_value = ImportUtils::EulerToQuaternion(quat_rotation_order, ImportUtils::deg2rad(rotation_key.second)); + Quaternion rot_key_value = ImportUtils::EulerToQuaternion(quaternion_rotation_order, ImportUtils::deg2rad(rotation_key.second)); - if (lastQuat != Quat() && rot_key_value.dot(lastQuat) < 0) { + if (lastQuaternion != Quaternion() && rot_key_value.dot(lastQuaternion) < 0) { rot_key_value.x = -rot_key_value.x; rot_key_value.y = -rot_key_value.y; rot_key_value.z = -rot_key_value.z; rot_key_value.w = -rot_key_value.w; } // pre_post rotation possibly could fix orientation - Quat final_rotation = pre_rotation * rot_key_value * post_rotation; + Quaternion final_rotation = pre_rotation * rot_key_value * post_rotation; - lastQuat = final_rotation; + lastQuaternion = final_rotation; if (animation_track_time > max_duration) { max_duration = animation_track_time; @@ -1165,7 +1165,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } bool valid_rest = false; - Transform bone_rest; + Transform3D bone_rest; int skeleton_bone = -1; if (state.fbx_bone_map.has(target_id)) { if (bone.is_valid() && bone->fbx_skeleton.is_valid()) { @@ -1182,13 +1182,13 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } const Vector3 def_pos = translation_keys.has_default ? (translation_keys.default_value * state.scale) : bone_rest.origin; - const Quat def_rot = rotation_keys.has_default ? ImportUtils::EulerToQuaternion(quat_rotation_order, ImportUtils::deg2rad(rotation_keys.default_value)) : bone_rest.basis.get_rotation_quat(); + const Quaternion def_rot = rotation_keys.has_default ? ImportUtils::EulerToQuaternion(quaternion_rotation_order, ImportUtils::deg2rad(rotation_keys.default_value)) : bone_rest.basis.get_rotation_quaternion(); const Vector3 def_scale = scale_keys.has_default ? scale_keys.default_value : bone_rest.basis.get_scale(); print_verbose("track defaults: p(" + def_pos + ") s(" + def_scale + ") r(" + def_rot + ")"); while (true) { Vector3 pos = def_pos; - Quat rot = def_rot; + Quaternion rot = def_rot; Vector3 scale = def_scale; if (pos_values.size()) { @@ -1197,7 +1197,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } if (rot_values.size()) { - rot = _interpolate_track<Quat>(rot_times, rot_values, time, + rot = _interpolate_track<Quaternion>(rot_times, rot_values, time, AssetImportAnimation::INTERP_LINEAR); } @@ -1208,13 +1208,13 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // node animations must also include pivots if (skeleton_bone >= 0) { - Transform xform = Transform(); - xform.basis.set_quat_scale(rot, scale); + Transform3D xform = Transform3D(); + xform.basis.set_quaternion_scale(rot, scale); xform.origin = pos; - const Transform t = bone_rest.affine_inverse() * xform; + const Transform3D t = bone_rest.affine_inverse() * xform; // populate this again - rot = t.basis.get_rotation_quat(); + rot = t.basis.get_rotation_quaternion(); rot.normalize(); scale = t.basis.get_scale(); pos = t.origin; diff --git a/modules/fbx/fbx_parser/FBXDeformer.cpp b/modules/fbx/fbx_parser/FBXDeformer.cpp index 039718ae15..4220ba62a7 100644 --- a/modules/fbx/fbx_parser/FBXDeformer.cpp +++ b/modules/fbx/fbx_parser/FBXDeformer.cpp @@ -78,7 +78,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXMeshGeometry.h" #include "FBXParser.h" #include "core/math/math_funcs.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include <iostream> diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h index e01e0471aa..885ff8fca4 100644 --- a/modules/fbx/fbx_parser/FBXDocument.h +++ b/modules/fbx/fbx_parser/FBXDocument.h @@ -37,7 +37,7 @@ #include "FBXCommon.h" #include "FBXParser.h" #include "FBXProperties.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/math/vector3.h" #include "core/string/print_string.h" @@ -242,13 +242,13 @@ public: return target_id; } - Transform GetBindPose() const { + Transform3D GetBindPose() const { return transform; } private: uint64_t target_id = 0; - Transform transform; + Transform3D transform; }; /** DOM base class for FBX cameras attached to a node */ @@ -905,11 +905,11 @@ public: } /** */ - const Transform &GetTransform() const { + const Transform3D &GetTransform() const { return transform; } - const Transform &TransformLink() const { + const Transform3D &TransformLink() const { return transformLink; } @@ -917,7 +917,7 @@ public: return node; } - const Transform &TransformAssociateModel() const { + const Transform3D &TransformAssociateModel() const { return transformAssociateModel; } @@ -941,9 +941,9 @@ private: std::vector<float> weights; std::vector<unsigned int> indices; - Transform transform; - Transform transformLink; - Transform transformAssociateModel; + Transform3D transform; + Transform3D transformLink; + Transform3D transformAssociateModel; SkinLinkMode link_mode; bool valid_transformAssociateModel = false; const Model *node = nullptr; diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp index 98435b5c0f..163518d18f 100644 --- a/modules/fbx/fbx_parser/FBXParser.cpp +++ b/modules/fbx/fbx_parser/FBXParser.cpp @@ -82,7 +82,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXParser.h" #include "FBXTokenizer.h" #include "core/math/math_defs.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector3.h" #include "core/string/print_string.h" @@ -1157,7 +1157,7 @@ void ParseVectorDataArray(std::vector<int64_t> &out, const ElementPtr el) { } // ------------------------------------------------------------------------------------------------ -Transform ReadMatrix(const ElementPtr element) { +Transform3D ReadMatrix(const ElementPtr element) { std::vector<float> values; ParseVectorDataArray(values, element); @@ -1172,7 +1172,7 @@ Transform ReadMatrix(const ElementPtr element) { } } - Transform xform; + Transform3D xform; Basis basis; basis.set( diff --git a/modules/fbx/fbx_parser/FBXParser.h b/modules/fbx/fbx_parser/FBXParser.h index 8b248e8791..93836c2205 100644 --- a/modules/fbx/fbx_parser/FBXParser.h +++ b/modules/fbx/fbx_parser/FBXParser.h @@ -81,7 +81,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory> #include "core/math/color.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/math/vector3.h" @@ -264,7 +264,7 @@ TokenPtr GetRequiredToken(const ElementPtr el, unsigned int index); // ------------------------------------------------------------------------------------------------ // read a 4x4 matrix from an array of 16 floats -Transform ReadMatrix(const ElementPtr element); +Transform3D ReadMatrix(const ElementPtr element); } // namespace FBXDocParser #endif // FBX_PARSER_H diff --git a/modules/fbx/tools/import_utils.cpp b/modules/fbx/tools/import_utils.cpp index 368aa09a75..66b0153308 100644 --- a/modules/fbx/tools/import_utils.cpp +++ b/modules/fbx/tools/import_utils.cpp @@ -80,7 +80,7 @@ Basis ImportUtils::EulerToBasis(FBXDocParser::Model::RotOrder mode, const Vector return ret; } -Quat ImportUtils::EulerToQuaternion(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation) { +Quaternion ImportUtils::EulerToQuaternion(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation) { return ImportUtils::EulerToBasis(mode, p_rotation); } @@ -117,13 +117,13 @@ Vector3 ImportUtils::BasisToEuler(FBXDocParser::Model::RotOrder mode, const Basi } } -Vector3 ImportUtils::QuaternionToEuler(FBXDocParser::Model::RotOrder mode, const Quat &p_rotation) { +Vector3 ImportUtils::QuaternionToEuler(FBXDocParser::Model::RotOrder mode, const Quaternion &p_rotation) { return BasisToEuler(mode, p_rotation); } -Transform get_unscaled_transform(const Transform &p_initial, real_t p_scale) { - Transform unscaled = Transform(p_initial.basis, p_initial.origin * p_scale); - ERR_FAIL_COND_V_MSG(unscaled.basis.determinant() == 0, Transform(), "det is zero unscaled?"); +Transform3D get_unscaled_transform(const Transform3D &p_initial, real_t p_scale) { + Transform3D unscaled = Transform3D(p_initial.basis, p_initial.origin * p_scale); + ERR_FAIL_COND_V_MSG(unscaled.basis.determinant() == 0, Transform3D(), "det is zero unscaled?"); return unscaled; } diff --git a/modules/fbx/tools/import_utils.h b/modules/fbx/tools/import_utils.h index cf0f811e35..7625f67256 100644 --- a/modules/fbx/tools/import_utils.h +++ b/modules/fbx/tools/import_utils.h @@ -56,15 +56,15 @@ public: static Basis EulerToBasis(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation); /// Converts rotation order vector (in rad) to quaternion. - static Quat EulerToQuaternion(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation); + static Quaternion EulerToQuaternion(FBXDocParser::Model::RotOrder mode, const Vector3 &p_rotation); /// Converts basis into rotation order vector (in rad). static Vector3 BasisToEuler(FBXDocParser::Model::RotOrder mode, const Basis &p_rotation); /// Converts quaternion into rotation order vector (in rad). - static Vector3 QuaternionToEuler(FBXDocParser::Model::RotOrder mode, const Quat &p_rotation); + static Vector3 QuaternionToEuler(FBXDocParser::Model::RotOrder mode, const Quaternion &p_rotation); - static void debug_xform(String name, const Transform &t) { + static void debug_xform(String name, const Transform3D &t) { print_verbose(name + " " + t.origin + " rotation: " + (t.basis.get_euler() * (180 / Math_PI))); } @@ -391,7 +391,7 @@ public: }; // Apply the transforms so the basis will have scale 1. -Transform get_unscaled_transform(const Transform &p_initial, real_t p_scale); +Transform3D get_unscaled_transform(const Transform3D &p_initial, real_t p_scale); /// Uses the Newell's method to compute any polygon normal. /// The polygon must be at least size of 3 or bigger. diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quaternion.cpp index 8ebcf7c91f..62bcbbd382 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quaternion.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quat.cpp */ +/* quaternion.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,31 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gdnative/quat.h" +#include "gdnative/quaternion.h" -#include "core/math/quat.h" +#include "core/math/quaternion.h" -static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch"); +static_assert(sizeof(godot_quaternion) == sizeof(Quaternion), "Quaternion size mismatch"); #ifdef __cplusplus extern "C" { #endif -void GDAPI godot_quat_new(godot_quat *p_self) { - memnew_placement(p_self, Quat); +void GDAPI godot_quaternion_new(godot_quaternion *p_self) { + memnew_placement(p_self, Quaternion); } -void GDAPI godot_quat_new_copy(godot_quat *r_dest, const godot_quat *p_src) { - memnew_placement(r_dest, Quat(*(Quat *)p_src)); +void GDAPI godot_quaternion_new_copy(godot_quaternion *r_dest, const godot_quaternion *p_src) { + memnew_placement(r_dest, Quaternion(*(Quaternion *)p_src)); } -godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index) { - Quat *self = (Quat *)p_self; +godot_real_t GDAPI *godot_quaternion_operator_index(godot_quaternion *p_self, godot_int p_index) { + Quaternion *self = (Quaternion *)p_self; return (godot_real_t *)&self->operator[](p_index); } -const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index) { - const Quat *self = (const Quat *)p_self; +const godot_real_t GDAPI *godot_quaternion_operator_index_const(const godot_quaternion *p_self, godot_int p_index) { + const Quaternion *self = (const Quaternion *)p_self; return (const godot_real_t *)&self->operator[](p_index); } diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform_3d.cpp index bfaaa13db2..8bd2a68d63 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* transform.cpp */ +/* transform_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,22 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gdnative/transform.h" +#include "gdnative/transform_3d.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" -static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch"); +static_assert(sizeof(godot_transform3d) == sizeof(Transform3D), "Transform3D size mismatch"); #ifdef __cplusplus extern "C" { #endif -void GDAPI godot_transform_new(godot_transform *p_self) { - memnew_placement(p_self, Transform); +void GDAPI godot_transform3d_new(godot_transform3d *p_self) { + memnew_placement(p_self, Transform3D); } -void GDAPI godot_transform_new_copy(godot_transform *r_dest, const godot_transform *p_src) { - memnew_placement(r_dest, Transform(*(Transform *)p_src)); +void GDAPI godot_transform3d_new_copy(godot_transform3d *r_dest, const godot_transform3d *p_src) { + memnew_placement(r_dest, Transform3D(*(Transform3D *)p_src)); } #ifdef __cplusplus diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 7801e21ab2..24f50a94f5 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -143,10 +143,10 @@ void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_p memnew_placement_custom(dest, Variant, Variant(*plane)); } -void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat) { +void GDAPI godot_variant_new_quaternion(godot_variant *r_dest, const godot_quaternion *p_quaternion) { Variant *dest = (Variant *)r_dest; - const Quat *quat = (const Quat *)p_quat; - memnew_placement_custom(dest, Variant, Variant(*quat)); + const Quaternion *quaternion = (const Quaternion *)p_quaternion; + memnew_placement_custom(dest, Variant, Variant(*quaternion)); } void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb) { @@ -161,9 +161,9 @@ void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_b memnew_placement_custom(dest, Variant, Variant(*basis)); } -void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans) { +void GDAPI godot_variant_new_transform3d(godot_variant *r_dest, const godot_transform3d *p_trans) { Variant *dest = (Variant *)r_dest; - const Transform *trans = (const Transform *)p_trans; + const Transform3D *trans = (const Transform3D *)p_trans; memnew_placement_custom(dest, Variant, Variant(*trans)); } @@ -378,10 +378,10 @@ godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self) { return raw_dest; } -godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self) { - godot_quat raw_dest; +godot_quaternion GDAPI godot_variant_as_quaternion(const godot_variant *p_self) { + godot_quaternion raw_dest; const Variant *self = (const Variant *)p_self; - Quat *dest = (Quat *)&raw_dest; + Quaternion *dest = (Quaternion *)&raw_dest; *dest = *self; return raw_dest; } @@ -402,10 +402,10 @@ godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self) { return raw_dest; } -godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self) { - godot_transform raw_dest; +godot_transform3d GDAPI godot_variant_as_transform3d(const godot_variant *p_self) { + godot_transform3d raw_dest; const Variant *self = (const Variant *)p_self; - Transform *dest = (Transform *)&raw_dest; + Transform3D *dest = (Transform3D *)&raw_dest; *dest = *self; return raw_dest; } diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 489083e795..175a6a3c91 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -469,7 +469,7 @@ ] }, { - "name": "godot_variant_new_quat", + "name": "godot_variant_new_quaternion", "return_type": "void", "arguments": [ [ @@ -477,8 +477,8 @@ "r_dest" ], [ - "const godot_quat *", - "p_quat" + "const godot_quaternion *", + "p_quaternion" ] ] }, @@ -511,7 +511,7 @@ ] }, { - "name": "godot_variant_new_transform", + "name": "godot_variant_new_transform3d", "return_type": "void", "arguments": [ [ @@ -519,7 +519,7 @@ "r_dest" ], [ - "const godot_transform *", + "const godot_transform3d *", "p_trans" ] ] @@ -893,8 +893,8 @@ ] }, { - "name": "godot_variant_as_quat", - "return_type": "godot_quat", + "name": "godot_variant_as_quaternion", + "return_type": "godot_quaternion", "arguments": [ [ "const godot_variant *", @@ -923,8 +923,8 @@ ] }, { - "name": "godot_variant_as_transform", - "return_type": "godot_transform", + "name": "godot_variant_as_transform3d", + "return_type": "godot_transform3d", "arguments": [ [ "const godot_variant *", @@ -3866,35 +3866,35 @@ ] }, { - "name": "godot_quat_new", + "name": "godot_quaternion_new", "return_type": "void", "arguments": [ [ - "godot_quat *", + "godot_quaternion *", "p_self" ] ] }, { - "name": "godot_quat_new_copy", + "name": "godot_quaternion_new_copy", "return_type": "void", "arguments": [ [ - "godot_quat *", + "godot_quaternion *", "r_dest" ], [ - "const godot_quat *", + "const godot_quaternion *", "p_src" ] ] }, { - "name": "godot_quat_operator_index", + "name": "godot_quaternion_operator_index", "return_type": "godot_real_t *", "arguments": [ [ - "godot_quat *", + "godot_quaternion *", "p_self" ], [ @@ -3904,11 +3904,11 @@ ] }, { - "name": "godot_quat_operator_index_const", + "name": "godot_quaternion_operator_index_const", "return_type": "const godot_real_t *", "arguments": [ [ - "const godot_quat *", + "const godot_quaternion *", "p_self" ], [ @@ -4344,25 +4344,25 @@ ] }, { - "name": "godot_transform_new", + "name": "godot_transform3d_new", "return_type": "void", "arguments": [ [ - "godot_transform *", + "godot_transform3d *", "r_dest" ] ] }, { - "name": "godot_transform_new_copy", + "name": "godot_transform3d_new_copy", "return_type": "void", "arguments": [ [ - "godot_transform *", + "godot_transform3d *", "r_dest" ], [ - "const godot_transform *", + "const godot_transform3d *", "p_src" ] ] @@ -5073,7 +5073,7 @@ }, { "name": "godot_xr_get_reference_frame", - "return_type": "godot_transform", + "return_type": "godot_transform3d", "arguments": [] }, { @@ -5145,7 +5145,7 @@ "p_controller_id" ], [ - "godot_transform *", + "godot_transform3d *", "p_transform" ], [ diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 9af9226a79..d8c290f6bd 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -149,9 +149,9 @@ typedef void godot_object; #include <gdnative/plane.h> -/////// Quat +/////// Quaternion -#include <gdnative/quat.h> +#include <gdnative/quaternion.h> /////// AABB @@ -161,9 +161,9 @@ typedef void godot_object; #include <gdnative/basis.h> -/////// Transform +/////// Transform3D -#include <gdnative/transform.h> +#include <gdnative/transform_3d.h> /////// Color diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quaternion.h index 00abdb4404..75754e6ab5 100644 --- a/modules/gdnative/include/gdnative/quat.h +++ b/modules/gdnative/include/gdnative/quaternion.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quat.h */ +/* quaternion.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_QUAT_H -#define GODOT_QUAT_H +#ifndef GODOT_QUATERNION_H +#define GODOT_QUATERNION_H #ifdef __cplusplus extern "C" { @@ -37,24 +37,24 @@ extern "C" { #include <gdnative/math_defs.h> -#define GODOT_QUAT_SIZE (sizeof(godot_real_t) * 4) +#define GODOT_QUATERNION_SIZE (sizeof(godot_real_t) * 4) -#ifndef GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED +#ifndef GODOT_CORE_API_GODOT_QUATERNION_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_QUATERNION_TYPE_DEFINED typedef struct { - uint8_t _dont_touch_that[GODOT_QUAT_SIZE]; -} godot_quat; + uint8_t _dont_touch_that[GODOT_QUATERNION_SIZE]; +} godot_quaternion; #endif #include <gdnative/gdnative.h> -void GDAPI godot_quat_new(godot_quat *p_self); -void GDAPI godot_quat_new_copy(godot_quat *r_dest, const godot_quat *p_src); -godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index); -const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index); +void GDAPI godot_quaternion_new(godot_quaternion *p_self); +void GDAPI godot_quaternion_new_copy(godot_quaternion *r_dest, const godot_quaternion *p_src); +godot_real_t GDAPI *godot_quaternion_operator_index(godot_quaternion *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_quaternion_operator_index_const(const godot_quaternion *p_self, godot_int p_index); #ifdef __cplusplus } #endif -#endif // GODOT_QUAT_H +#endif // GODOT_QUATERNION_H diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform_3d.h index 3861b5683a..97ad451e9b 100644 --- a/modules/gdnative/include/gdnative/transform.h +++ b/modules/gdnative/include/gdnative/transform_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* transform.h */ +/* transform_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_TRANSFORM_H -#define GODOT_TRANSFORM_H +#ifndef GODOT_TRANSFORM3D_H +#define GODOT_TRANSFORM3D_H #ifdef __cplusplus extern "C" { @@ -37,22 +37,24 @@ extern "C" { #include <gdnative/math_defs.h> -#define GODOT_TRANSFORM_SIZE (sizeof(godot_real_t) * 12) +#define GODOT_TRANSFORM3D_SIZE (sizeof(godot_real_t) * 12) -#ifndef GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED +#ifndef GODOT_CORE_API_GODOT_TRANSFORM3D_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_TRANSFORM3D_TYPE_DEFINED typedef struct { - uint8_t _dont_touch_that[GODOT_TRANSFORM_SIZE]; -} godot_transform; + uint8_t _dont_touch_that[GODOT_TRANSFORM3D_SIZE]; +} godot_transform3d; #endif #include <gdnative/gdnative.h> -void GDAPI godot_transform_new(godot_transform *p_self); -void GDAPI godot_transform_new_copy(godot_transform *r_dest, const godot_transform *p_src); +void GDAPI godot_transform3d_new(godot_transform3d *p_self); +void GDAPI godot_transform3d_new_copy(godot_transform3d *r_dest, const godot_transform3d *p_src); +godot_vector3 GDAPI *godot_transform3d_operator_index(godot_transform3d *p_self, godot_int p_index); +const godot_vector3 GDAPI *godot_transform3d_operator_index_const(const godot_transform3d *p_self, godot_int p_index); #ifdef __cplusplus } #endif -#endif // GODOT_TRANSFORM_H +#endif // GODOT_TRANSFORM3D_H diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index 3e06ed9aa4..dd4f76cf57 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -56,10 +56,10 @@ typedef enum godot_variant_type { GODOT_VARIANT_TYPE_VECTOR3I, GODOT_VARIANT_TYPE_TRANSFORM2D, GODOT_VARIANT_TYPE_PLANE, - GODOT_VARIANT_TYPE_QUAT, + GODOT_VARIANT_TYPE_QUATERNION, GODOT_VARIANT_TYPE_AABB, GODOT_VARIANT_TYPE_BASIS, - GODOT_VARIANT_TYPE_TRANSFORM, + GODOT_VARIANT_TYPE_TRANSFORM3D, // misc types GODOT_VARIANT_TYPE_COLOR, @@ -177,14 +177,14 @@ typedef void (*godot_ptr_utility_function)(void *r_return, const void **p_argume #include <gdnative/node_path.h> #include <gdnative/packed_arrays.h> #include <gdnative/plane.h> -#include <gdnative/quat.h> +#include <gdnative/quaternion.h> #include <gdnative/rect2.h> #include <gdnative/rid.h> #include <gdnative/signal.h> #include <gdnative/string.h> #include <gdnative/string_name.h> -#include <gdnative/transform.h> #include <gdnative/transform2d.h> +#include <gdnative/transform_3d.h> #include <gdnative/variant.h> #include <gdnative/vector2.h> #include <gdnative/vector3.h> @@ -208,10 +208,10 @@ void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3); void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d); void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane); -void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat); +void GDAPI godot_variant_new_quaternion(godot_variant *r_dest, const godot_quaternion *p_quaternion); void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb); void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis); -void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans); +void GDAPI godot_variant_new_transform3d(godot_variant *r_dest, const godot_transform3d *p_trans); void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color); void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s); void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np); @@ -243,10 +243,10 @@ godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self); godot_vector3i GDAPI godot_variant_as_vector3i(const godot_variant *p_self); godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self); godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self); -godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self); +godot_quaternion GDAPI godot_variant_as_quaternion(const godot_variant *p_self); godot_aabb GDAPI godot_variant_as_aabb(const godot_variant *p_self); godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self); -godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self); +godot_transform3d GDAPI godot_variant_as_transform3d(const godot_variant *p_self); godot_color GDAPI godot_variant_as_color(const godot_variant *p_self); godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self); godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self); diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h index b76f89cc99..34ed4f097d 100644 --- a/modules/gdnative/include/pluginscript/godot_pluginscript.h +++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h @@ -61,7 +61,7 @@ typedef struct { //this is used by script languages that keep a reference counter of their own //you can make make Ref<> not die when it reaches zero, so deleting the reference //depends entirely from the script. - // Note: You can set those function pointer to nullptr if not needed. + // Note: You can set those function pointer to nullptr if not needed. void (*refcount_incremented)(godot_pluginscript_instance_data *p_data); bool (*refcount_decremented)(godot_pluginscript_instance_data *p_data); // return true if it can die } godot_pluginscript_instance_desc; @@ -121,12 +121,12 @@ typedef struct { const char *name; const char *type; const char *extension; - const char **recognized_extensions; // nullptr terminated array + const char **recognized_extensions; // nullptr terminated array godot_pluginscript_language_data *(*init)(); void (*finish)(godot_pluginscript_language_data *p_data); - const char **reserved_words; // nullptr terminated array - const char **comment_delimiters; // nullptr terminated array - const char **string_delimiters; // nullptr terminated array + const char **reserved_words; // nullptr terminated array + const char **comment_delimiters; // nullptr terminated array + const char **string_delimiters; // nullptr terminated array godot_bool has_named_classes; godot_bool supports_builtin_mode; godot_bool can_inherit_from_file; diff --git a/modules/gdnative/include/xr/godot_xr.h b/modules/gdnative/include/xr/godot_xr.h index 7eaf1c7ec3..e09244f3f9 100644 --- a/modules/gdnative/include/xr/godot_xr.h +++ b/modules/gdnative/include/xr/godot_xr.h @@ -57,7 +57,7 @@ typedef struct { godot_bool (*initialize)(void *); void (*uninitialize)(void *); godot_vector2 (*get_render_targetsize)(const void *); - godot_transform (*get_transform_for_eye)(void *, godot_int, godot_transform *); + godot_transform3d (*get_transform_for_eye)(void *, godot_int, godot_transform3d *); void (*fill_projection_for_eye)(void *, godot_float *, godot_int, godot_float, godot_float, godot_float); void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *); void (*process)(void *); @@ -70,7 +70,7 @@ void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_inte // helper functions to access XRServer data godot_float GDAPI godot_xr_get_worldscale(); -godot_transform GDAPI godot_xr_get_reference_frame(); +godot_transform3d GDAPI godot_xr_get_reference_frame(); // helper functions for rendering void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect); @@ -79,7 +79,7 @@ godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target); // helper functions for updating XR controllers godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position); void GDAPI godot_xr_remove_controller(godot_int p_controller_id); -void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position); +void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform3d *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position); void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed); void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_float p_value, godot_bool p_can_be_negative); godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id); diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index b2abf8b8ae..b10a747568 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -70,8 +70,7 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char const NativeScriptDesc *b = desc.base_data; while (b) { - desc.rpc_count += b->rpc_count; - desc.rset_count += b->rset_count; + desc.rpc_methods.append_array(b->rpc_methods); b = b->base_data; } @@ -94,8 +93,6 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const desc.destroy_func = p_destroy_func; desc.is_tool = true; desc.base = p_base; - desc.rpc_count = 0; - desc.rset_count = 0; if (classes->has(p_base)) { desc.base_data = &(*classes)[p_base]; @@ -103,8 +100,7 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const const NativeScriptDesc *b = desc.base_data; while (b) { - desc.rpc_count += b->rpc_count; - desc.rset_count += b->rset_count; + desc.rpc_methods.append_array(b->rpc_methods); b = b->base_data; } @@ -126,13 +122,16 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha method.method = p_method; method.rpc_mode = p_attr.rpc_type; method.rpc_method_id = UINT16_MAX; - if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) { - method.rpc_method_id = E->get().rpc_count; - E->get().rpc_count += 1; - } method.info = MethodInfo(p_function_name); E->get().methods.insert(p_function_name, method); + + if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) { + MultiplayerAPI::RPCConfig nd; + nd.name = String(p_name); + nd.rpc_mode = MultiplayerAPI::RPCMode(p_attr.rpc_type); + E->get().rpc_methods.push_back(nd); + } } void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const char *p_name, const char *p_path, godot_nativescript_property_attributes *p_attr, godot_nativescript_property_set_func p_set_func, godot_nativescript_property_get_func p_get_func) { @@ -144,11 +143,6 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c NativeScriptDesc::Property property; property.default_value = *(Variant *)&p_attr->default_value; property.getter = p_get_func; - property.rset_mode = p_attr->rset_type; - if (p_attr->rset_type != GODOT_METHOD_RPC_MODE_DISABLED) { - property.rset_property_id = E->get().rset_count; - E->get().rset_count += 1; - } property.setter = p_set_func; property.info = PropertyInfo((Variant::Type)p_attr->type, p_path, diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 46af70f73c..03e25f49e6 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -415,245 +415,11 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const { } } -Vector<ScriptNetData> NativeScript::get_rpc_methods() const { - Vector<ScriptNetData> v; - - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { - if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) { - ScriptNetData nd; - nd.name = E->key(); - nd.mode = MultiplayerAPI::RPCMode(E->get().rpc_mode); - v.push_back(nd); - } - } - - script_data = script_data->base_data; - } - - return v; -} - -uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const { - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); - if (E) { - return E->get().rpc_method_id; - } - - script_data = script_data->base_data; - } - - return UINT16_MAX; -} - -StringName NativeScript::get_rpc_method(uint16_t p_id) const { - ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName()); - +const Vector<MultiplayerAPI::RPCConfig> NativeScript::get_rpc_methods() const { NativeScriptDesc *script_data = get_script_desc(); + ERR_FAIL_COND_V(!script_data, Vector<MultiplayerAPI::RPCConfig>()); - while (script_data) { - for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { - if (E->get().rpc_method_id == p_id) { - return E->key(); - } - } - - script_data = script_data->base_data; - } - - return StringName(); -} - -MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const { - ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED); - - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { - if (E->get().rpc_method_id == p_id) { - switch (E->get().rpc_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } - } - - script_data = script_data->base_data; - } - - return MultiplayerAPI::RPC_MODE_DISABLED; -} - -MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const { - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); - if (E) { - switch (E->get().rpc_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } - - script_data = script_data->base_data; - } - - return MultiplayerAPI::RPC_MODE_DISABLED; -} - -Vector<ScriptNetData> NativeScript::get_rset_properties() const { - Vector<ScriptNetData> v; - - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { - if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) { - ScriptNetData nd; - nd.name = E.key(); - nd.mode = MultiplayerAPI::RPCMode(E.get().rset_mode); - v.push_back(nd); - } - } - script_data = script_data->base_data; - } - - return v; -} - -uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const { - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); - if (E) { - return E.get().rset_property_id; - } - - script_data = script_data->base_data; - } - - return UINT16_MAX; -} - -StringName NativeScript::get_rset_property(uint16_t p_id) const { - ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName()); - - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { - if (E.get().rset_property_id == p_id) { - return E.key(); - } - } - - script_data = script_data->base_data; - } - - return StringName(); -} - -MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const { - ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED); - - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { - if (E.get().rset_property_id == p_id) { - switch (E.get().rset_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } - } - - script_data = script_data->base_data; - } - - return MultiplayerAPI::RPC_MODE_DISABLED; -} - -MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const { - NativeScriptDesc *script_data = get_script_desc(); - - while (script_data) { - OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); - if (E) { - switch (E.get().rset_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } - - script_data = script_data->base_data; - } - - return MultiplayerAPI::RPC_MODE_DISABLED; + return script_data->rpc_methods; } String NativeScript::get_class_documentation() const { @@ -1046,46 +812,10 @@ Ref<Script> NativeScriptInstance::get_script() const { return script; } -Vector<ScriptNetData> NativeScriptInstance::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> NativeScriptInstance::get_rpc_methods() const { return script->get_rpc_methods(); } -uint16_t NativeScriptInstance::get_rpc_method_id(const StringName &p_method) const { - return script->get_rpc_method_id(p_method); -} - -StringName NativeScriptInstance::get_rpc_method(uint16_t p_id) const { - return script->get_rpc_method(p_id); -} - -MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const { - return script->get_rpc_mode_by_id(p_id); -} - -MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { - return script->get_rpc_mode(p_method); -} - -Vector<ScriptNetData> NativeScriptInstance::get_rset_properties() const { - return script->get_rset_properties(); -} - -uint16_t NativeScriptInstance::get_rset_property_id(const StringName &p_variable) const { - return script->get_rset_property_id(p_variable); -} - -StringName NativeScriptInstance::get_rset_property(uint16_t p_id) const { - return script->get_rset_property(p_id); -} - -MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode_by_id(uint16_t p_id) const { - return script->get_rset_mode_by_id(p_id); -} - -MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { - return script->get_rset_mode(p_variable); -} - ScriptLanguage *NativeScriptInstance::get_language() { return NativeScriptLanguage::get_singleton(); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index ca5e76e43e..1756321281 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -62,8 +62,6 @@ struct NativeScriptDesc { godot_nativescript_property_get_func getter; PropertyInfo info; Variant default_value; - int rset_mode = 0; - uint16_t rset_property_id; String documentation; }; @@ -72,9 +70,8 @@ struct NativeScriptDesc { String documentation; }; - uint16_t rpc_count = 0; Map<StringName, Method> methods; - uint16_t rset_count = 0; + Vector<MultiplayerAPI::RPCConfig> rpc_methods; OrderedHashMap<StringName, Property> properties; Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; @@ -178,17 +175,7 @@ public: virtual void get_script_method_list(List<MethodInfo> *p_list) const override; virtual void get_script_property_list(List<PropertyInfo> *p_list) const override; - virtual Vector<ScriptNetData> get_rpc_methods() const override; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; - virtual StringName get_rpc_method(uint16_t p_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - virtual Vector<ScriptNetData> get_rset_properties() const override; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const override; - virtual StringName get_rset_property(uint16_t p_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; String get_class_documentation() const; String get_method_documentation(const StringName &p_method) const; @@ -226,17 +213,7 @@ public: String to_string(bool *r_valid); virtual Ref<Script> get_script() const; - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const; virtual ScriptLanguage *get_language(); diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index 7f8dba0906..ed1c0af3ed 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -100,46 +100,10 @@ String PluginScriptInstance::to_string(bool *r_valid) { return str_ret; } -Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> PluginScriptInstance::get_rpc_methods() const { return _script->get_rpc_methods(); } -uint16_t PluginScriptInstance::get_rpc_method_id(const StringName &p_variable) const { - return _script->get_rpc_method_id(p_variable); -} - -StringName PluginScriptInstance::get_rpc_method(uint16_t p_id) const { - return _script->get_rpc_method(p_id); -} - -MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const { - return _script->get_rpc_mode_by_id(p_id); -} - -MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { - return _script->get_rpc_mode(p_method); -} - -Vector<ScriptNetData> PluginScriptInstance::get_rset_properties() const { - return _script->get_rset_properties(); -} - -uint16_t PluginScriptInstance::get_rset_property_id(const StringName &p_variable) const { - return _script->get_rset_property_id(p_variable); -} - -StringName PluginScriptInstance::get_rset_property(uint16_t p_id) const { - return _script->get_rset_property(p_id); -} - -MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode_by_id(uint16_t p_id) const { - return _script->get_rset_mode_by_id(p_id); -} - -MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { - return _script->get_rset_mode(p_variable); -} - void PluginScriptInstance::refcount_incremented() { if (_desc->refcount_decremented) { _desc->refcount_incremented(_data); diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index b263c0e62c..25b62ae8ab 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -71,17 +71,7 @@ public: void set_path(const String &p_path); - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const; virtual void refcount_incremented(); virtual bool refcount_decremented(); diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index a48245814f..6bb11d3e8f 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -312,10 +312,9 @@ Error PluginScript::reload(bool p_keep_state) { } Array *methods = (Array *)&manifest.methods; _rpc_methods.clear(); - _rpc_variables.clear(); if (_ref_base_parent.is_valid()) { + /// XXX TODO Should this be _rpc_methods.append_array(...) _rpc_methods = _ref_base_parent->get_rpc_methods(); - _rpc_variables = _ref_base_parent->get_rset_properties(); } for (int i = 0; i < methods->size(); ++i) { Dictionary v = (*methods)[i]; @@ -324,9 +323,10 @@ Error PluginScript::reload(bool p_keep_state) { // rpc_mode is passed as an optional field and is not part of MethodInfo Variant var = v["rpc_mode"]; if (var != Variant()) { - ScriptNetData nd; + MultiplayerAPI::RPCConfig nd; nd.name = mi.name; - nd.mode = MultiplayerAPI::RPCMode(int(var)); + nd.rpc_mode = MultiplayerAPI::RPCMode(int(var)); + // TODO Transfer Channel if (_rpc_methods.find(nd) == -1) { _rpc_methods.push_back(nd); } @@ -334,7 +334,7 @@ Error PluginScript::reload(bool p_keep_state) { } // Sort so we are 100% that they are always the same. - _rpc_methods.sort_custom<SortNetData>(); + _rpc_methods.sort_custom<MultiplayerAPI::SortRPCConfig>(); Array *signals = (Array *)&manifest.signals; for (int i = 0; i < signals->size(); ++i) { @@ -348,21 +348,8 @@ Error PluginScript::reload(bool p_keep_state) { PropertyInfo pi = PropertyInfo::from_dict(v); _properties_info[pi.name] = pi; _properties_default_values[pi.name] = v["default_value"]; - // rset_mode is passed as an optional field and is not part of PropertyInfo - Variant var = v["rset_mode"]; - if (var != Variant()) { - ScriptNetData nd; - nd.name = pi.name; - nd.mode = MultiplayerAPI::RPCMode(int(var)); - if (_rpc_variables.find(nd) == -1) { - _rpc_variables.push_back(nd); - } - } } - // Sort so we are 100% that they are always the same. - _rpc_variables.sort_custom<SortNetData>(); - #ifdef TOOLS_ENABLED /*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { @@ -486,76 +473,10 @@ int PluginScript::get_member_line(const StringName &p_member) const { return -1; } -Vector<ScriptNetData> PluginScript::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> PluginScript::get_rpc_methods() const { return _rpc_methods; } -uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const { - ASSERT_SCRIPT_VALID_V(UINT16_MAX); - for (int i = 0; i < _rpc_methods.size(); i++) { - if (_rpc_methods[i].name == p_method) { - return i; - } - } - return UINT16_MAX; -} - -StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const { - ASSERT_SCRIPT_VALID_V(StringName()); - if (p_rpc_method_id >= _rpc_methods.size()) { - return StringName(); - } - return _rpc_methods[p_rpc_method_id].name; -} - -MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - if (p_rpc_method_id >= _rpc_methods.size()) { - return MultiplayerAPI::RPC_MODE_DISABLED; - } - return _rpc_methods[p_rpc_method_id].mode; -} - -MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { - ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - return get_rpc_mode_by_id(get_rpc_method_id(p_method)); -} - -Vector<ScriptNetData> PluginScript::get_rset_properties() const { - return _rpc_variables; -} - -uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const { - ASSERT_SCRIPT_VALID_V(UINT16_MAX); - for (int i = 0; i < _rpc_variables.size(); i++) { - if (_rpc_variables[i].name == p_property) { - return i; - } - } - return UINT16_MAX; -} - -StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const { - ASSERT_SCRIPT_VALID_V(StringName()); - if (p_rset_property_id >= _rpc_variables.size()) { - return StringName(); - } - return _rpc_variables[p_rset_property_id].name; -} - -MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) const { - ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - if (p_rset_property_id >= _rpc_variables.size()) { - return MultiplayerAPI::RPC_MODE_DISABLED; - } - return _rpc_variables[p_rset_property_id].mode; -} - -MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { - ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - return get_rset_mode_by_id(get_rset_property_id(p_variable)); -} - PluginScript::PluginScript() : _script_list(this) { } diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 1c86f2056d..97989a19d8 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -61,8 +61,7 @@ private: Map<StringName, PropertyInfo> _properties_info; Map<StringName, MethodInfo> _signals_info; Map<StringName, MethodInfo> _methods_info; - Vector<ScriptNetData> _rpc_methods; - Vector<ScriptNetData> _rpc_variables; + Vector<MultiplayerAPI::RPCConfig> _rpc_methods; Set<Object *> _instances; //exported members @@ -137,17 +136,7 @@ public: virtual int get_member_line(const StringName &p_member) const override; - virtual Vector<ScriptNetData> get_rpc_methods() const override; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - virtual Vector<ScriptNetData> get_rset_properties() const override; - virtual uint16_t get_rset_property_id(const StringName &p_property) const override; - virtual StringName get_rset_property(const uint16_t p_rset_property_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; PluginScript(); void init(PluginScriptLanguage *language); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index d08bde9e23..cf19c0c44c 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -363,7 +363,7 @@ void unregister_gdnative_types() { print_line(String("aabb:\t") + itos(sizeof(AABB))); print_line(String("rid:\t") + itos(sizeof(RID))); print_line(String("string:\t") + itos(sizeof(String))); - print_line(String("transform:\t") + itos(sizeof(Transform))); + print_line(String("transform:\t") + itos(sizeof(Transform3D))); print_line(String("transfo2D:\t") + itos(sizeof(Transform2D))); print_line(String("variant:\t") + itos(sizeof(Variant))); print_line(String("vector2:\t") + itos(sizeof(Vector2))); diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp index 122cb5849b..258fb75000 100644 --- a/modules/gdnative/xr/xr_interface_gdnative.cpp +++ b/modules/gdnative/xr/xr_interface_gdnative.cpp @@ -173,14 +173,14 @@ Size2 XRInterfaceGDNative::get_render_targetsize() { return *vec; } -Transform XRInterfaceGDNative::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { - Transform *ret; +Transform3D XRInterfaceGDNative::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) { + Transform3D *ret; - ERR_FAIL_COND_V(interface == nullptr, Transform()); + ERR_FAIL_COND_V(interface == nullptr, Transform3D()); - godot_transform t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform *)&p_cam_transform); + godot_transform3d t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform3d *)&p_cam_transform); - ret = (Transform *)&t; + ret = (Transform3D *)&t; return *ret; } @@ -241,15 +241,15 @@ godot_float GDAPI godot_xr_get_worldscale() { return xr_server->get_world_scale(); } -godot_transform GDAPI godot_xr_get_reference_frame() { - godot_transform reference_frame; - Transform *reference_frame_ptr = (Transform *)&reference_frame; +godot_transform3d GDAPI godot_xr_get_reference_frame() { + godot_transform3d reference_frame; + Transform3D *reference_frame_ptr = (Transform3D *)&reference_frame; XRServer *xr_server = XRServer::get_singleton(); if (xr_server != nullptr) { *reference_frame_ptr = xr_server->get_reference_frame(); } else { - memnew_placement(&reference_frame, Transform); + memnew_placement(&reference_frame, Transform3D); } return reference_frame; @@ -356,13 +356,13 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) { } } -void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { +void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform3d *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker.is_valid()) { - Transform *transform = (Transform *)p_transform; + Transform3D *transform = (Transform3D *)p_transform; if (p_tracks_orientation) { tracker->set_orientation(transform->basis); } diff --git a/modules/gdnative/xr/xr_interface_gdnative.h b/modules/gdnative/xr/xr_interface_gdnative.h index 84bd8fc731..42098ebeff 100644 --- a/modules/gdnative/xr/xr_interface_gdnative.h +++ b/modules/gdnative/xr/xr_interface_gdnative.h @@ -73,7 +73,7 @@ public: /** rendering and internal **/ virtual Size2 get_render_targetsize() override; virtual bool is_stereo() override; - virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) override; + virtual Transform3D get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) override; // we expose a Vector<float> version of this function to GDNative Vector<float> _get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp index 88ef434e0f..d5e6e5e69f 100644 --- a/modules/gdnavigation/gd_navigation_server.cpp +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -270,7 +270,7 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) { } } -COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform) { +COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) { NavRegion *region = region_owner.getornull(p_region); ERR_FAIL_COND(region == nullptr); diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h index 2f51f6431e..759d15e508 100644 --- a/modules/gdnavigation/gd_navigation_server.h +++ b/modules/gdnavigation/gd_navigation_server.h @@ -113,7 +113,7 @@ public: COMMAND_2(region_set_map, RID, p_region, RID, p_map); COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers); virtual uint32_t region_get_layers(RID p_region) const; - COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform); + COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform); COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh); virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const; virtual int region_get_connections_count(RID p_region) const; diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp index c1690b2a4b..81b15a49f5 100644 --- a/modules/gdnavigation/nav_region.cpp +++ b/modules/gdnavigation/nav_region.cpp @@ -52,7 +52,7 @@ uint32_t NavRegion::get_layers() const { return layers; } -void NavRegion::set_transform(Transform p_transform) { +void NavRegion::set_transform(Transform3D p_transform) { transform = p_transform; polygons_dirty = true; } diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h index 527b2500ac..f8b067e638 100644 --- a/modules/gdnavigation/nav_region.h +++ b/modules/gdnavigation/nav_region.h @@ -46,7 +46,7 @@ class NavRegion; class NavRegion : public NavRid { NavMap *map = nullptr; - Transform transform; + Transform3D transform; Ref<NavigationMesh> mesh; uint32_t layers = 1; Vector<gd::Edge::Connection> connections; @@ -71,8 +71,8 @@ public: void set_layers(uint32_t p_layers); uint32_t get_layers() const; - void set_transform(Transform transform); - const Transform &get_transform() const { + void set_transform(Transform3D transform); + const Transform3D &get_transform() const { return transform; } diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp index 7d30ce0f44..d69c9114b9 100644 --- a/modules/gdnavigation/navigation_mesh_generator.cpp +++ b/modules/gdnavigation/navigation_mesh_generator.cpp @@ -68,7 +68,7 @@ void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> & p_verticies.push_back(p_vec3.z); } -void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { int current_vertex_count; for (int i = 0; i < p_mesh->get_surface_count(); i++) { @@ -123,7 +123,7 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform } } -void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { int face_count = p_faces.size() / 3; int current_vertex_count = p_verticies.size() / 3; @@ -138,7 +138,7 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons } } -void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { +void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node); Ref<Mesh> mesh = mesh_instance->get_mesh(); @@ -169,7 +169,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, if (Object::cast_to<CollisionShape3D>(child)) { CollisionShape3D *col_shape = Object::cast_to<CollisionShape3D>(child); - Transform transform = p_accumulated_transform * static_body->get_transform() * col_shape->get_transform(); + Transform3D transform = p_accumulated_transform * static_body->get_transform() * col_shape->get_transform(); Ref<Mesh> mesh; Ref<Shape3D> s = col_shape->get_shape(); @@ -251,7 +251,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, if (Object::cast_to<GridMap>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { GridMap *gridmap_instance = Object::cast_to<GridMap>(p_node); Array meshes = gridmap_instance->get_meshes(); - Transform xform = gridmap_instance->get_transform(); + Transform3D xform = gridmap_instance->get_transform(); for (int i = 0; i < meshes.size(); i += 2) { Ref<Mesh> mesh = meshes[i + 1]; if (mesh.is_valid()) { @@ -513,7 +513,7 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) p_node->get_tree()->get_nodes_in_group(p_nav_mesh->get_source_group_name(), &parse_nodes); } - Transform navmesh_xform = Object::cast_to<Node3D>(p_node)->get_transform().affine_inverse(); + Transform3D navmesh_xform = Object::cast_to<Node3D>(p_node)->get_transform().affine_inverse(); for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) { int geometry_type = p_nav_mesh->get_parsed_geometry_type(); uint32_t collision_mask = p_nav_mesh->get_collision_mask(); diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h index 88ccdb1c41..847c7d097b 100644 --- a/modules/gdnavigation/navigation_mesh_generator.h +++ b/modules/gdnavigation/navigation_mesh_generator.h @@ -50,9 +50,9 @@ protected: static void _bind_methods(); static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies); - static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); - static void _add_faces(const PackedVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); - static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); + static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); + static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices); + static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh); static void _build_recast_navigation_mesh( diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index d34cccb3af..b867b03903 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -64,6 +64,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) bool in_function_args = false; bool in_member_variable = false; bool in_node_path = false; + bool in_annotation = false; bool is_hex_notation = false; bool is_bin_notation = false; bool expect_type = false; @@ -357,9 +358,18 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) in_node_path = false; } + if (!in_annotation && in_region == -1 && str[j] == '@') { + in_annotation = true; + } else if (in_region != -1 || is_a_symbol) { + in_annotation = false; + } + if (in_node_path) { next_type = NODE_PATH; color = node_path_color; + } else if (in_annotation) { + next_type = ANNOTATION; + color = annotation_color; } else if (in_keyword) { next_type = KEYWORD; color = keyword_color; @@ -546,19 +556,22 @@ void GDScriptSyntaxHighlighter::_update_cache() { } const String text_edit_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - const bool default_theme = text_edit_color_theme == "Godot 2"; + const bool godot_2_theme = text_edit_color_theme == "Godot 2"; - if (default_theme || EditorSettings::get_singleton()->is_dark_theme()) { + if (godot_2_theme || EditorSettings::get_singleton()->is_dark_theme()) { function_definition_color = Color(0.4, 0.9, 1.0); node_path_color = Color(0.39, 0.76, 0.35); + annotation_color = Color(1.0, 0.7, 0.45); } else { function_definition_color = Color(0.0, 0.65, 0.73); node_path_color = Color(0.32, 0.55, 0.29); + annotation_color = Color(0.8, 0.5, 0.25); } EDITOR_DEF("text_editor/highlighting/gdscript/function_definition_color", function_definition_color); EDITOR_DEF("text_editor/highlighting/gdscript/node_path_color", node_path_color); - if (text_edit_color_theme == "Default" || default_theme) { + EDITOR_DEF("text_editor/highlighting/gdscript/annotation_color", annotation_color); + if (text_edit_color_theme == "Default" || godot_2_theme) { EditorSettings::get_singleton()->set_initial_value( "text_editor/highlighting/gdscript/function_definition_color", function_definition_color, @@ -567,10 +580,15 @@ void GDScriptSyntaxHighlighter::_update_cache() { "text_editor/highlighting/gdscript/node_path_color", node_path_color, true); + EditorSettings::get_singleton()->set_initial_value( + "text_editor/highlighting/gdscript/annotation_color", + annotation_color, + true); } function_definition_color = EDITOR_GET("text_editor/highlighting/gdscript/function_definition_color"); node_path_color = EDITOR_GET("text_editor/highlighting/gdscript/node_path_color"); + annotation_color = EDITOR_GET("text_editor/highlighting/gdscript/annotation_color"); type_color = EDITOR_GET("text_editor/highlighting/base_type_color"); } diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index 1b57cb1923..d07c182aa6 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -54,6 +54,7 @@ private: NONE, REGION, NODE_PATH, + ANNOTATION, SYMBOL, NUMBER, FUNCTION, @@ -72,6 +73,7 @@ private: Color number_color; Color member_color; Color node_path_color; + Color annotation_color; Color type_color; void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index d7814e85b0..e99c3d6cca 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -897,68 +897,10 @@ void GDScript::get_members(Set<StringName> *p_members) { } } -Vector<ScriptNetData> GDScript::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> GDScript::get_rpc_methods() const { return rpc_functions; } -uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const { - for (int i = 0; i < rpc_functions.size(); i++) { - if (rpc_functions[i].name == p_method) { - return i; - } - } - return UINT16_MAX; -} - -StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const { - if (p_rpc_method_id >= rpc_functions.size()) { - return StringName(); - } - return rpc_functions[p_rpc_method_id].name; -} - -MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - if (p_rpc_method_id >= rpc_functions.size()) { - return MultiplayerAPI::RPC_MODE_DISABLED; - } - return rpc_functions[p_rpc_method_id].mode; -} - -MultiplayerAPI::RPCMode GDScript::get_rpc_mode(const StringName &p_method) const { - return get_rpc_mode_by_id(get_rpc_method_id(p_method)); -} - -Vector<ScriptNetData> GDScript::get_rset_properties() const { - return rpc_variables; -} - -uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const { - for (int i = 0; i < rpc_variables.size(); i++) { - if (rpc_variables[i].name == p_variable) { - return i; - } - } - return UINT16_MAX; -} - -StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const { - if (p_rset_member_id >= rpc_variables.size()) { - return StringName(); - } - return rpc_variables[p_rset_member_id].name; -} - -MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - if (p_rset_member_id >= rpc_variables.size()) { - return MultiplayerAPI::RPC_MODE_DISABLED; - } - return rpc_variables[p_rset_member_id].mode; -} - -MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const { - return get_rset_mode_by_id(get_rset_property_id(p_variable)); -} - Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *top = this; while (top) { @@ -1210,10 +1152,8 @@ void GDScript::_save_orphaned_subclasses() { void GDScript::_init_rpc_methods_properties() { // Copy the base rpc methods so we don't mask their IDs. rpc_functions.clear(); - rpc_variables.clear(); if (base.is_valid()) { rpc_functions = base->rpc_functions; - rpc_variables = base->rpc_variables; } GDScript *cscript = this; @@ -1222,25 +1162,17 @@ void GDScript::_init_rpc_methods_properties() { // RPC Methods for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { - ScriptNetData nd; + MultiplayerAPI::RPCConfig nd; nd.name = E->key(); - nd.mode = E->get()->get_rpc_mode(); + nd.rpc_mode = E->get()->get_rpc_mode(); + // TODO + nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; + nd.channel = 0; if (-1 == rpc_functions.find(nd)) { rpc_functions.push_back(nd); } } } - // RSet - for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) { - if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { - ScriptNetData nd; - nd.name = E->key(); - nd.mode = E->get().rpc_mode; - if (-1 == rpc_variables.find(nd)) { - rpc_variables.push_back(nd); - } - } - } if (cscript != this) { sub_E = sub_E->next(); @@ -1254,8 +1186,7 @@ void GDScript::_init_rpc_methods_properties() { } // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<SortNetData>(); - rpc_variables.sort_custom<SortNetData>(); + rpc_functions.sort_custom<MultiplayerAPI::SortRPCConfig>(); } GDScript::~GDScript() { @@ -1611,46 +1542,10 @@ ScriptLanguage *GDScriptInstance::get_language() { return GDScriptLanguage::get_singleton(); } -Vector<ScriptNetData> GDScriptInstance::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> GDScriptInstance::get_rpc_methods() const { return script->get_rpc_methods(); } -uint16_t GDScriptInstance::get_rpc_method_id(const StringName &p_method) const { - return script->get_rpc_method_id(p_method); -} - -StringName GDScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { - return script->get_rpc_method(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - return script->get_rpc_mode_by_id(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const { - return script->get_rpc_mode(p_method); -} - -Vector<ScriptNetData> GDScriptInstance::get_rset_properties() const { - return script->get_rset_properties(); -} - -uint16_t GDScriptInstance::get_rset_property_id(const StringName &p_variable) const { - return script->get_rset_property_id(p_variable); -} - -StringName GDScriptInstance::get_rset_property(const uint16_t p_rset_member_id) const { - return script->get_rset_property(p_rset_member_id); -} - -MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - return script->get_rset_mode_by_id(p_rset_member_id); -} - -MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const { - return script->get_rset_mode(p_variable); -} - void GDScriptInstance::reload_members() { #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 6df66e876d..8b1b859ca2 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -86,8 +86,7 @@ class GDScript : public Script { Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script. Map<StringName, Ref<GDScript>> subclasses; Map<StringName, Vector<StringName>> _signals; - Vector<ScriptNetData> rpc_functions; - Vector<ScriptNetData> rpc_variables; + Vector<MultiplayerAPI::RPCConfig> rpc_functions; #ifdef TOOLS_ENABLED @@ -247,17 +246,7 @@ public: virtual void get_constants(Map<StringName, Variant> *p_constants) override; virtual void get_members(Set<StringName> *p_members) override; - virtual Vector<ScriptNetData> get_rpc_methods() const override; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - virtual Vector<ScriptNetData> get_rset_properties() const override; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const override; - virtual StringName get_rset_property(const uint16_t p_variable_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; #ifdef TOOLS_ENABLED virtual bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -310,17 +299,7 @@ public: void reload_members(); - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const; GDScriptInstance(); ~GDScriptInstance(); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index d8d60b35c6..e92adee8e8 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2825,7 +2825,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::RECT2: case Variant::RECT2I: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::OBJECT: error = index_type.builtin_type != Variant::STRING; @@ -2836,8 +2836,8 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::VECTOR2I: case Variant::VECTOR3: case Variant::VECTOR3I: - case Variant::TRANSFORM: case Variant::TRANSFORM2D: + case Variant::TRANSFORM3D: error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT && index_type.builtin_type != Variant::STRING; break; @@ -2904,7 +2904,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PACKED_FLOAT64_ARRAY: case Variant::VECTOR2: case Variant::VECTOR3: - case Variant::QUAT: + case Variant::QUATERNION: result_type.builtin_type = Variant::FLOAT; break; // Return Color. @@ -2933,7 +2933,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri result_type.builtin_type = Variant::VECTOR3; break; // Depends on the index. - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: case Variant::PLANE: case Variant::COLOR: case Variant::DICTIONARY: diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 77a972ef12..6998cc5bb7 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -85,10 +85,10 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type case Variant::VECTOR3I: case Variant::TRANSFORM2D: case Variant::PLANE: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::AABB: case Variant::BASIS: - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: case Variant::COLOR: case Variant::STRING_NAME: case Variant::NODE_PATH: @@ -458,8 +458,8 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::PLANE: append(GDScriptFunction::OPCODE_TYPE_ADJUST_PLANE, 1); break; - case Variant::QUAT: - append(GDScriptFunction::OPCODE_TYPE_ADJUST_QUAT, 1); + case Variant::QUATERNION: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_QUATERNION, 1); break; case Variant::AABB: append(GDScriptFunction::OPCODE_TYPE_ADJUST_AABB, 1); @@ -467,7 +467,7 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::BASIS: append(GDScriptFunction::OPCODE_TYPE_ADJUST_BASIS, 1); break; - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM, 1); break; case Variant::COLOR: @@ -1100,12 +1100,12 @@ void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, cons CASE_TYPE(PLANE); CASE_TYPE(AABB); CASE_TYPE(BASIS); - CASE_TYPE(TRANSFORM); + CASE_TYPE(TRANSFORM3D); CASE_TYPE(COLOR); CASE_TYPE(STRING_NAME); CASE_TYPE(NODE_PATH); CASE_TYPE(RID); - CASE_TYPE(QUAT); + CASE_TYPE(QUATERNION); CASE_TYPE(OBJECT); CASE_TYPE(CALLABLE); CASE_TYPE(SIGNAL); diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index eee713aa45..1acb9ceddc 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -620,12 +620,12 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_PTRCALL(PLANE); DISASSEMBLE_PTRCALL(AABB); DISASSEMBLE_PTRCALL(BASIS); - DISASSEMBLE_PTRCALL(TRANSFORM); + DISASSEMBLE_PTRCALL(TRANSFORM3D); DISASSEMBLE_PTRCALL(COLOR); DISASSEMBLE_PTRCALL(STRING_NAME); DISASSEMBLE_PTRCALL(NODE_PATH); DISASSEMBLE_PTRCALL(RID); - DISASSEMBLE_PTRCALL(QUAT); + DISASSEMBLE_PTRCALL(QUATERNION); DISASSEMBLE_PTRCALL(OBJECT); DISASSEMBLE_PTRCALL(CALLABLE); DISASSEMBLE_PTRCALL(SIGNAL); @@ -957,7 +957,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_TYPE_ADJUST(VECTOR3I); DISASSEMBLE_TYPE_ADJUST(TRANSFORM2D); DISASSEMBLE_TYPE_ADJUST(PLANE); - DISASSEMBLE_TYPE_ADJUST(QUAT); + DISASSEMBLE_TYPE_ADJUST(QUATERNION); DISASSEMBLE_TYPE_ADJUST(AABB); DISASSEMBLE_TYPE_ADJUST(BASIS); DISASSEMBLE_TYPE_ADJUST(TRANSFORM); diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 26b8809337..cd1704cb03 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -278,10 +278,10 @@ public: OPCODE_CALL_PTRCALL_VECTOR3I, OPCODE_CALL_PTRCALL_TRANSFORM2D, OPCODE_CALL_PTRCALL_PLANE, - OPCODE_CALL_PTRCALL_QUAT, + OPCODE_CALL_PTRCALL_QUATERNION, OPCODE_CALL_PTRCALL_AABB, OPCODE_CALL_PTRCALL_BASIS, - OPCODE_CALL_PTRCALL_TRANSFORM, + OPCODE_CALL_PTRCALL_TRANSFORM3D, OPCODE_CALL_PTRCALL_COLOR, OPCODE_CALL_PTRCALL_STRING_NAME, OPCODE_CALL_PTRCALL_NODE_PATH, @@ -365,7 +365,7 @@ public: OPCODE_TYPE_ADJUST_VECTOR3I, OPCODE_TYPE_ADJUST_TRANSFORM2D, OPCODE_TYPE_ADJUST_PLANE, - OPCODE_TYPE_ADJUST_QUAT, + OPCODE_TYPE_ADJUST_QUATERNION, OPCODE_TYPE_ADJUST_AABB, OPCODE_TYPE_ADJUST_BASIS, OPCODE_TYPE_ADJUST_TRANSFORM, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index b61b469fbc..1af54ea8df 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -61,9 +61,9 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { builtin_types["Vector3i"] = Variant::VECTOR3I; builtin_types["AABB"] = Variant::AABB; builtin_types["Plane"] = Variant::PLANE; - builtin_types["Quat"] = Variant::QUAT; + builtin_types["Quaternion"] = Variant::QUATERNION; builtin_types["Basis"] = Variant::BASIS; - builtin_types["Transform"] = Variant::TRANSFORM; + builtin_types["Transform"] = Variant::TRANSFORM3D; builtin_types["Color"] = Variant::COLOR; builtin_types["RID"] = Variant::RID; builtin_types["Object"] = Variant::OBJECT; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 56b0f6db83..318ec966ae 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -166,10 +166,10 @@ void (*type_init_function_table[])(Variant *) = { &VariantInitializer<Vector3i>::init, // VECTOR3I. &VariantInitializer<Transform2D>::init, // TRANSFORM2D. &VariantInitializer<Plane>::init, // PLANE. - &VariantInitializer<Quat>::init, // QUAT. + &VariantInitializer<Quaternion>::init, // QUATERNION. &VariantInitializer<AABB>::init, // AABB. &VariantInitializer<Basis>::init, // BASIS. - &VariantInitializer<Transform>::init, // TRANSFORM. + &VariantInitializer<Transform3D>::init, // TRANSFORM3D. &VariantInitializer<Color>::init, // COLOR. &VariantInitializer<StringName>::init, // STRING_NAME. &VariantInitializer<NodePath>::init, // NODE_PATH. @@ -248,10 +248,10 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_CALL_PTRCALL_VECTOR3I, \ &&OPCODE_CALL_PTRCALL_TRANSFORM2D, \ &&OPCODE_CALL_PTRCALL_PLANE, \ - &&OPCODE_CALL_PTRCALL_QUAT, \ + &&OPCODE_CALL_PTRCALL_QUATERNION, \ &&OPCODE_CALL_PTRCALL_AABB, \ &&OPCODE_CALL_PTRCALL_BASIS, \ - &&OPCODE_CALL_PTRCALL_TRANSFORM, \ + &&OPCODE_CALL_PTRCALL_TRANSFORM3D, \ &&OPCODE_CALL_PTRCALL_COLOR, \ &&OPCODE_CALL_PTRCALL_STRING_NAME, \ &&OPCODE_CALL_PTRCALL_NODE_PATH, \ @@ -335,7 +335,7 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_TYPE_ADJUST_VECTOR3I, \ &&OPCODE_TYPE_ADJUST_TRANSFORM2D, \ &&OPCODE_TYPE_ADJUST_PLANE, \ - &&OPCODE_TYPE_ADJUST_QUAT, \ + &&OPCODE_TYPE_ADJUST_QUATERNION, \ &&OPCODE_TYPE_ADJUST_AABB, \ &&OPCODE_TYPE_ADJUST_BASIS, \ &&OPCODE_TYPE_ADJUST_TRANSFORM, \ @@ -398,7 +398,7 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_VECTOR3I get_vector3i #define OP_GET_RECT2 get_rect2 #define OP_GET_RECT2I get_rect2i -#define OP_GET_QUAT get_quat +#define OP_GET_QUATERNION get_quaternion #define OP_GET_COLOR get_color #define OP_GET_STRING get_string #define OP_GET_STRING_NAME get_string_name @@ -416,7 +416,7 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_PACKED_VECTOR2_ARRAY get_vector2_array #define OP_GET_PACKED_VECTOR3_ARRAY get_vector3_array #define OP_GET_PACKED_COLOR_ARRAY get_color_array -#define OP_GET_TRANSFORM get_transform +#define OP_GET_TRANSFORM3D get_transform #define OP_GET_TRANSFORM2D get_transform2d #define OP_GET_PLANE get_plane #define OP_GET_AABB get_aabb @@ -1733,10 +1733,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_CALL_PTR(VECTOR3I); OPCODE_CALL_PTR(TRANSFORM2D); OPCODE_CALL_PTR(PLANE); - OPCODE_CALL_PTR(QUAT); + OPCODE_CALL_PTR(QUATERNION); OPCODE_CALL_PTR(AABB); OPCODE_CALL_PTR(BASIS); - OPCODE_CALL_PTR(TRANSFORM); + OPCODE_CALL_PTR(TRANSFORM3D); OPCODE_CALL_PTR(COLOR); OPCODE_CALL_PTR(STRING_NAME); OPCODE_CALL_PTR(NODE_PATH); @@ -3150,10 +3150,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_TYPE_ADJUST(VECTOR3I, Vector3i); OPCODE_TYPE_ADJUST(TRANSFORM2D, Transform2D); OPCODE_TYPE_ADJUST(PLANE, Plane); - OPCODE_TYPE_ADJUST(QUAT, Quat); + OPCODE_TYPE_ADJUST(QUATERNION, Quaternion); OPCODE_TYPE_ADJUST(AABB, AABB); OPCODE_TYPE_ADJUST(BASIS, Basis); - OPCODE_TYPE_ADJUST(TRANSFORM, Transform); + OPCODE_TYPE_ADJUST(TRANSFORM, Transform3D); OPCODE_TYPE_ADJUST(COLOR, Color); OPCODE_TYPE_ADJUST(STRING_NAME, StringName); OPCODE_TYPE_ADJUST(NODE_PATH, NodePath); diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml index af7be55e4b..5d84d7088b 100644 --- a/modules/gltf/doc_classes/GLTFNode.xml +++ b/modules/gltf/doc_classes/GLTFNode.xml @@ -23,7 +23,7 @@ </member> <member name="parent" type="int" setter="set_parent" getter="get_parent" default="-1"> </member> - <member name="rotation" type="Quat" setter="set_rotation" getter="get_rotation" default="Quat( 0, 0, 0, 1 )"> + <member name="rotation" type="Quaternion" setter="set_rotation" getter="get_rotation" default="Quaternion( 0, 0, 0, 1 )"> </member> <member name="scale" type="Vector3" setter="set_scale" getter="get_scale" default="Vector3( 1, 1, 1 )"> </member> @@ -33,7 +33,7 @@ </member> <member name="translation" type="Vector3" setter="set_translation" getter="get_translation" default="Vector3( 0, 0, 0 )"> </member> - <member name="xform" type="Transform" setter="set_xform" getter="get_xform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + <member name="xform" type="Transform3D" setter="set_xform" getter="get_xform" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </member> </members> <constants> diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/gltf_animation.h index a494e6bd67..216d2161c4 100644 --- a/modules/gltf/gltf_animation.h +++ b/modules/gltf/gltf_animation.h @@ -56,7 +56,7 @@ public: struct Track { Channel<Vector3> translation_track; - Channel<Quat> rotation_track; + Channel<Quaternion> rotation_track; Channel<Vector3> scale_track; Vector<Channel<float>> weight_tracks; }; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index abac0a2e17..fa93704fd9 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -342,25 +342,25 @@ static Vector3 _arr_to_vec3(const Array &p_array) { return Vector3(p_array[0], p_array[1], p_array[2]); } -static Array _quat_to_array(const Quat &p_quat) { +static Array _quaternion_to_array(const Quaternion &p_quaternion) { Array array; array.resize(4); - array[0] = p_quat.x; - array[1] = p_quat.y; - array[2] = p_quat.z; - array[3] = p_quat.w; + array[0] = p_quaternion.x; + array[1] = p_quaternion.y; + array[2] = p_quaternion.z; + array[3] = p_quaternion.w; return array; } -static Quat _arr_to_quat(const Array &p_array) { - ERR_FAIL_COND_V(p_array.size() != 4, Quat()); - return Quat(p_array[0], p_array[1], p_array[2], p_array[3]); +static Quaternion _arr_to_quaternion(const Array &p_array) { + ERR_FAIL_COND_V(p_array.size() != 4, Quaternion()); + return Quaternion(p_array[0], p_array[1], p_array[2], p_array[3]); } -static Transform _arr_to_xform(const Array &p_array) { - ERR_FAIL_COND_V(p_array.size() != 16, Transform()); +static Transform3D _arr_to_xform(const Array &p_array) { + ERR_FAIL_COND_V(p_array.size() != 16, Transform3D()); - Transform xform; + Transform3D xform; xform.basis.set_axis(Vector3::AXIS_X, Vector3(p_array[0], p_array[1], p_array[2])); xform.basis.set_axis(Vector3::AXIS_Y, Vector3(p_array[4], p_array[5], p_array[6])); xform.basis.set_axis(Vector3::AXIS_Z, Vector3(p_array[8], p_array[9], p_array[10])); @@ -369,7 +369,7 @@ static Transform _arr_to_xform(const Array &p_array) { return xform; } -static Vector<real_t> _xform_to_array(const Transform p_transform) { +static Vector<real_t> _xform_to_array(const Transform3D p_transform) { Vector<real_t> array; array.resize(16); Vector3 axis_x = p_transform.get_basis().get_axis(Vector3::AXIS_X); @@ -421,12 +421,12 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) { } if (n->skeleton != -1 && n->skin < 0) { } - if (n->xform != Transform()) { + if (n->xform != Transform3D()) { node["matrix"] = _xform_to_array(n->xform); } - if (!n->rotation.is_equal_approx(Quat())) { - node["rotation"] = _quat_to_array(n->rotation); + if (!n->rotation.is_equal_approx(Quaternion())) { + node["rotation"] = _quaternion_to_array(n->rotation); } if (!n->scale.is_equal_approx(Vector3(1.0f, 1.0f, 1.0f))) { @@ -591,13 +591,13 @@ Error GLTFDocument::_parse_nodes(Ref<GLTFState> state) { node->translation = _arr_to_vec3(n["translation"]); } if (n.has("rotation")) { - node->rotation = _arr_to_quat(n["rotation"]); + node->rotation = _arr_to_quaternion(n["rotation"]); } if (n.has("scale")) { node->scale = _arr_to_vec3(n["scale"]); } - node->xform.basis.set_quat_scale(node->rotation, node->scale); + node->xform.basis.set_quaternion_scale(node->rotation, node->scale); node->xform.origin = node->translation; } @@ -1779,7 +1779,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> state, return state->accessors.size() - 1; } -GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quats(Ref<GLTFState> state, const Vector<Quat> p_attribs, const bool p_for_vertex) { +GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> state, const Vector<Quaternion> p_attribs, const bool p_for_vertex) { if (p_attribs.size() == 0) { return -1; } @@ -1794,11 +1794,11 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quats(Ref<GLTFState> state, Vector<double> type_min; type_min.resize(element_count); for (int i = 0; i < p_attribs.size(); i++) { - Quat quat = p_attribs[i]; - attribs.write[(i * element_count) + 0] = Math::snapped(quat.x, CMP_NORMALIZE_TOLERANCE); - attribs.write[(i * element_count) + 1] = Math::snapped(quat.y, CMP_NORMALIZE_TOLERANCE); - attribs.write[(i * element_count) + 2] = Math::snapped(quat.z, CMP_NORMALIZE_TOLERANCE); - attribs.write[(i * element_count) + 3] = Math::snapped(quat.w, CMP_NORMALIZE_TOLERANCE); + Quaternion quaternion = p_attribs[i]; + attribs.write[(i * element_count) + 0] = Math::snapped(quaternion.x, CMP_NORMALIZE_TOLERANCE); + attribs.write[(i * element_count) + 1] = Math::snapped(quaternion.y, CMP_NORMALIZE_TOLERANCE); + attribs.write[(i * element_count) + 2] = Math::snapped(quaternion.z, CMP_NORMALIZE_TOLERANCE); + attribs.write[(i * element_count) + 3] = Math::snapped(quaternion.w, CMP_NORMALIZE_TOLERANCE); _calc_accessor_min_max(i, element_count, type_max, attribs, type_min); } @@ -1939,7 +1939,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> state, c return state->accessors.size() - 1; } -GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state, const Vector<Transform> p_attribs, const bool p_for_vertex) { +GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state, const Vector<Transform3D> p_attribs, const bool p_for_vertex) { if (p_attribs.size() == 0) { return -1; } @@ -1953,7 +1953,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state, Vector<double> type_min; type_min.resize(element_count); for (int i = 0; i < p_attribs.size(); i++) { - Transform attrib = p_attribs[i]; + Transform3D attrib = p_attribs[i]; Basis basis = attrib.get_basis(); Vector3 axis_0 = basis.get_axis(Vector3::AXIS_X); @@ -2053,9 +2053,9 @@ Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> state, cons } return ret; } -Vector<Quat> GLTFDocument::_decode_accessor_as_quat(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) { +Vector<Quaternion> GLTFDocument::_decode_accessor_as_quaternion(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) { const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex); - Vector<Quat> ret; + Vector<Quaternion> ret; if (attribs.size() == 0) { return ret; @@ -2067,7 +2067,7 @@ Vector<Quat> GLTFDocument::_decode_accessor_as_quat(Ref<GLTFState> state, const ret.resize(ret_size); { for (int i = 0; i < ret_size; i++) { - ret.write[i] = Quat(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized(); + ret.write[i] = Quaternion(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]).normalized(); } } return ret; @@ -2107,9 +2107,9 @@ Vector<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> state, cons return ret; } -Vector<Transform> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) { +Vector<Transform3D> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) { const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex); - Vector<Transform> ret; + Vector<Transform3D> ret; if (attribs.size() == 0) { return ret; @@ -4279,7 +4279,7 @@ Error GLTFDocument::_create_skins(Ref<GLTFState> state) { GLTFNodeIndex node = gltf_skin->joints_original[joint_i]; String bone_name = state->nodes[node]->get_name(); - Transform xform; + Transform3D xform; if (has_ibms) { xform = gltf_skin->inverse_binds[joint_i]; } @@ -4323,8 +4323,8 @@ bool GLTFDocument::_skins_are_same(const Ref<Skin> skin_a, const Ref<Skin> skin_ return false; } - Transform a_xform = skin_a->get_bind_pose(i); - Transform b_xform = skin_b->get_bind_pose(i); + Transform3D a_xform = skin_a->get_bind_pose(i); + Transform3D b_xform = skin_b->get_bind_pose(i); if (a_xform != b_xform) { return false; @@ -4607,8 +4607,8 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { s["interpolation"] = interpolation_to_string(track.rotation_track.interpolation); Vector<real_t> times = Variant(track.rotation_track.times); s["input"] = _encode_accessor_as_floats(state, times, false); - Vector<Quat> values = track.rotation_track.values; - s["output"] = _encode_accessor_as_quats(state, values, false); + Vector<Quaternion> values = track.rotation_track.values; + s["output"] = _encode_accessor_as_quaternions(state, values, false); samplers.push_back(s); @@ -4777,7 +4777,7 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { track->translation_track.times = Variant(times); //convert via variant track->translation_track.values = Variant(translations); //convert via variant } else if (path == "rotation") { - const Vector<Quat> rotations = _decode_accessor_as_quat(state, output, false); + const Vector<Quaternion> rotations = _decode_accessor_as_quaternion(state, output, false); track->rotation_track.interpolation = interp; track->rotation_track.times = Variant(times); //convert via variant track->rotation_track.values = rotations; @@ -5075,9 +5075,9 @@ GLTFSkeletonIndex GLTFDocument::_convert_skeleton(Ref<GLTFState> state, Skeleton } void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref<GLTFNode> p_node) { - Transform xform = p_spatial->get_transform(); + Transform3D xform = p_spatial->get_transform(); p_node->scale = xform.basis.get_scale(); - p_node->rotation = xform.basis.get_rotation_quat(); + p_node->rotation = xform.basis.get_rotation_quaternion(); p_node->translation = xform.origin; } @@ -5240,7 +5240,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNod Vector3(cell_location.x, cell_location.y, cell_location.z)); EditorSceneImporterMeshNode3D *import_mesh_node = memnew(EditorSceneImporterMeshNode3D); import_mesh_node->set_mesh(grid_map->get_mesh_library()->get_item_mesh(cell)); - Transform cell_xform; + Transform3D cell_xform; cell_xform.basis.set_orthogonal_index( grid_map->get_cell_item_orientation( Vector3(cell_location.x, cell_location.y, cell_location.z))); @@ -5268,15 +5268,15 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count(); instance_i++) { GLTFNode *new_gltf_node = memnew(GLTFNode); - Transform transform; + Transform3D transform; if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_2D) { Transform2D xform_2d = multi_mesh->get_instance_transform_2d(instance_i); transform.origin = Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y); real_t rotation = xform_2d.get_rotation(); - Quat quat(Vector3(0, 1, 0), rotation); + Quaternion quaternion(Vector3(0, 1, 0), rotation); Size2 scale = xform_2d.get_scale(); - transform.basis.set_quat_scale(quat, + transform.basis.set_quaternion_scale(quaternion, Vector3(scale.x, 0, scale.y)); transform = multi_mesh_instance->get_transform() * transform; @@ -5516,24 +5516,24 @@ struct EditorSceneImporterGLTFInterpolate { // thank you for existing, partial specialization template <> -struct EditorSceneImporterGLTFInterpolate<Quat> { - Quat lerp(const Quat &a, const Quat &b, const float c) const { - ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quat(), "The quaternion \"a\" must be normalized."); - ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quat(), "The quaternion \"b\" must be normalized."); +struct EditorSceneImporterGLTFInterpolate<Quaternion> { + Quaternion lerp(const Quaternion &a, const Quaternion &b, const float c) const { + ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quaternion(), "The quaternion \"a\" must be normalized."); + ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quaternion(), "The quaternion \"b\" must be normalized."); return a.slerp(b, c).normalized(); } - Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, const float c) { - ERR_FAIL_COND_V_MSG(!p1.is_normalized(), Quat(), "The quaternion \"p1\" must be normalized."); - ERR_FAIL_COND_V_MSG(!p2.is_normalized(), Quat(), "The quaternion \"p2\" must be normalized."); + Quaternion catmull_rom(const Quaternion &p0, const Quaternion &p1, const Quaternion &p2, const Quaternion &p3, const float c) { + ERR_FAIL_COND_V_MSG(!p1.is_normalized(), Quaternion(), "The quaternion \"p1\" must be normalized."); + ERR_FAIL_COND_V_MSG(!p2.is_normalized(), Quaternion(), "The quaternion \"p2\" must be normalized."); return p1.slerp(p2, c).normalized(); } - Quat bezier(const Quat start, const Quat control_1, const Quat control_2, const Quat end, const float t) { - ERR_FAIL_COND_V_MSG(!start.is_normalized(), Quat(), "The start quaternion must be normalized."); - ERR_FAIL_COND_V_MSG(!end.is_normalized(), Quat(), "The end quaternion must be normalized."); + Quaternion bezier(const Quaternion start, const Quaternion control_1, const Quaternion control_2, const Quaternion end, const float t) { + ERR_FAIL_COND_V_MSG(!start.is_normalized(), Quaternion(), "The start quaternion must be normalized."); + ERR_FAIL_COND_V_MSG(!end.is_normalized(), Quaternion(), "The end quaternion must be normalized."); return start.slerp(end, t).normalized(); } @@ -5673,7 +5673,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, if ((track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) { //make transform track int track_idx = animation->get_track_count(); - animation->add_track(Animation::TYPE_TRANSFORM); + animation->add_track(Animation::TYPE_TRANSFORM3D); animation->track_set_path(track_idx, transform_node_path); //first determine animation length @@ -5681,7 +5681,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, double time = 0.0; Vector3 base_pos; - Quat base_rot; + Quaternion base_rot; Vector3 base_scale = Vector3(1, 1, 1); if (!track.rotation_track.values.size()) { @@ -5699,7 +5699,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, bool last = false; while (true) { Vector3 pos = base_pos; - Quat rot = base_rot; + Quaternion rot = base_rot; Vector3 scale = base_scale; if (track.translation_track.times.size()) { @@ -5707,7 +5707,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, } if (track.rotation_track.times.size()) { - rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation); + rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation); } if (track.scale_track.times.size()) { @@ -5715,15 +5715,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, } if (gltf_node->skeleton >= 0) { - Transform xform; - xform.basis.set_quat_scale(rot, scale); + Transform3D xform; + xform.basis.set_quaternion_scale(rot, scale); xform.origin = pos; const Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton; const int bone_idx = skeleton->find_bone(gltf_node->get_name()); xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform; - rot = xform.basis.get_rotation_quat(); + rot = xform.basis.get_rotation_quaternion(); rot.normalize(); scale = xform.basis.get_scale(); pos = xform.origin; @@ -5808,9 +5808,9 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { } MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get()); ERR_CONTINUE(!mi); - Transform mi_xform = mi->get_transform(); + Transform3D mi_xform = mi->get_transform(); node->scale = mi_xform.basis.get_scale(); - node->rotation = mi_xform.basis.get_rotation_quat(); + node->rotation = mi_xform.basis.get_rotation_quaternion(); node->translation = mi_xform.origin; Dictionary json_skin; @@ -5872,9 +5872,9 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { String gltf_bone_name = _gen_unique_bone_name(state, skeleton_gltf_i, godot_bone_name); joint_node->set_name(gltf_bone_name); - Transform bone_rest_xform = skeleton->get_bone_rest(bone_index); + Transform3D bone_rest_xform = skeleton->get_bone_rest(bone_index); joint_node->scale = bone_rest_xform.basis.get_scale(); - joint_node->rotation = bone_rest_xform.basis.get_rotation_quat(); + joint_node->rotation = bone_rest_xform.basis.get_rotation_quaternion(); joint_node->translation = bone_rest_xform.origin; joint_node->joint = true; @@ -5995,12 +5995,12 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo mi->set_skin(state->skins.write[skin_i]->godot_skin); mi->set_skeleton_path(mi->get_path_to(skeleton)); - mi->set_transform(Transform()); + mi->set_transform(Transform3D()); } } } -GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, Transform p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i) { +GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, Transform3D p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i) { Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i); GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; @@ -6020,7 +6020,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i); } const float BAKE_FPS = 30.0f; - if (track_type == Animation::TYPE_TRANSFORM) { + if (track_type == Animation::TYPE_TRANSFORM3D) { p_track.translation_track.times = times; p_track.translation_track.interpolation = gltf_interpolation; p_track.rotation_track.times = times; @@ -6036,16 +6036,16 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { Vector3 translation; - Quat rotation; + Quaternion rotation; Vector3 scale; Error err = p_animation->transform_track_get_key(p_track_i, key_i, &translation, &rotation, &scale); ERR_CONTINUE(err != OK); - Transform xform; - xform.basis.set_quat_scale(rotation, scale); + Transform3D xform; + xform.basis.set_quaternion_scale(rotation, scale); xform.origin = translation; xform = p_bone_rest * xform; p_track.translation_track.values.write[key_i] = xform.get_origin(); - p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quat(); + p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion(); p_track.scale_track.values.write[key_i] = xform.basis.get_scale(); } } else if (path.find(":transform") != -1) { @@ -6063,9 +6063,9 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state p_track.rotation_track.values.resize(key_count); p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { - Transform xform = p_animation->track_get_key_value(p_track_i, key_i); + Transform3D xform = p_animation->track_get_key_value(p_track_i, key_i); p_track.translation_track.values.write[key_i] = xform.get_origin(); - p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quat(); + p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion(); p_track.scale_track.values.write[key_i] = xform.basis.get_scale(); } } else if (track_type == Animation::TYPE_VALUE) { @@ -6077,7 +6077,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state p_track.rotation_track.interpolation = gltf_interpolation; for (int32_t key_i = 0; key_i < key_count; key_i++) { - Quat rotation_track = p_animation->track_get_key_value(p_track_i, key_i); + Quaternion rotation_track = p_animation->track_get_key_value(p_track_i, key_i); p_track.rotation_track.values.write[key_i] = rotation_track; } } else if (path.find(":translation") != -1) { @@ -6104,7 +6104,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state rotation_radian.x = Math::deg2rad(rotation_degrees.x); rotation_radian.y = Math::deg2rad(rotation_degrees.y); rotation_radian.z = Math::deg2rad(rotation_degrees.z); - p_track.rotation_track.values.write[key_i] = Quat(rotation_radian); + p_track.rotation_track.values.write[key_i] = Quaternion(rotation_radian); } } else if (path.find(":scale") != -1) { p_track.scale_track.times = times; @@ -6210,7 +6210,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (translation_track_i) { track = translation_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6226,7 +6226,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (rotation_degree_track_i) { track = rotation_degree_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6242,7 +6242,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (scale_track_i) { track = scale_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); } } @@ -6253,7 +6253,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, for (Map<GLTFNodeIndex, Node *>::Element *transform_track_i = state->scene_nodes.front(); transform_track_i; transform_track_i = transform_track_i->next()) { if (transform_track_i->get() == node) { GLTFAnimation::Track track; - track = _convert_animation_track(state, track, animation, Transform(), track_i, transform_track_i->key()); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i->key()); gltf_animation->get_tracks().insert(transform_track_i->key(), track); } } @@ -6341,7 +6341,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, Ref<GLTFSkeleton> skeleton_gltf = state->skeletons[skeleton_gltf_i]; int32_t bone = skeleton->find_bone(suffix); ERR_CONTINUE(bone == -1); - Transform xform = skeleton->get_bone_rest(bone); + Transform3D xform = skeleton->get_bone_rest(bone); if (!skeleton_gltf->godot_bone_node.has(bone)) { continue; } @@ -6368,7 +6368,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, if (node_track_i) { track = node_track_i->get(); } - track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index); gltf_animation->get_tracks().insert(node_index, track); break; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 900c367010..514373c4f0 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -205,7 +205,7 @@ private: Vector<Color> _decode_accessor_as_color(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex); - Vector<Quat> _decode_accessor_as_quat(Ref<GLTFState> state, + Vector<Quaternion> _decode_accessor_as_quaternion(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex); Vector<Transform2D> _decode_accessor_as_xform2d(Ref<GLTFState> state, @@ -214,7 +214,7 @@ private: Vector<Basis> _decode_accessor_as_basis(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex); - Vector<Transform> _decode_accessor_as_xform(Ref<GLTFState> state, + Vector<Transform3D> _decode_accessor_as_xform(Ref<GLTFState> state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex); Error _parse_meshes(Ref<GLTFState> state); @@ -273,8 +273,8 @@ private: T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp); - GLTFAccessorIndex _encode_accessor_as_quats(Ref<GLTFState> state, - const Vector<Quat> p_attribs, + GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> state, + const Vector<Quaternion> p_attribs, const bool p_for_vertex); GLTFAccessorIndex _encode_accessor_as_weights(Ref<GLTFState> state, const Vector<Color> p_attribs, @@ -317,7 +317,7 @@ private: const Vector<int32_t> p_attribs, const bool p_for_vertex); GLTFAccessorIndex _encode_accessor_as_xform(Ref<GLTFState> state, - const Vector<Transform> p_attribs, + const Vector<Transform3D> p_attribs, const bool p_for_vertex); Error _encode_buffer_view(Ref<GLTFState> state, const double *src, const int count, const GLTFType type, @@ -333,7 +333,7 @@ private: String interpolation_to_string(const GLTFAnimation::Interpolation p_interp); GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, - Ref<Animation> p_animation, Transform p_bone_rest, + Ref<Animation> p_animation, Transform3D p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i); Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path); diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/gltf_node.cpp index f6f33ef009..5db7ad66c3 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/gltf_node.cpp @@ -60,14 +60,14 @@ void GLTFNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "parent"), "set_parent", "get_parent"); // GLTFNodeIndex ADD_PROPERTY(PropertyInfo(Variant::INT, "height"), "set_height", "get_height"); // int - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "xform"), "set_xform", "get_xform"); // Transform + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "xform"), "set_xform", "get_xform"); // Transform3D ADD_PROPERTY(PropertyInfo(Variant::INT, "mesh"), "set_mesh", "get_mesh"); // GLTFMeshIndex ADD_PROPERTY(PropertyInfo(Variant::INT, "camera"), "set_camera", "get_camera"); // GLTFCameraIndex ADD_PROPERTY(PropertyInfo(Variant::INT, "skin"), "set_skin", "get_skin"); // GLTFSkinIndex ADD_PROPERTY(PropertyInfo(Variant::INT, "skeleton"), "set_skeleton", "get_skeleton"); // GLTFSkeletonIndex ADD_PROPERTY(PropertyInfo(Variant::BOOL, "joint"), "set_joint", "get_joint"); // bool ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation"), "set_translation", "get_translation"); // Vector3 - ADD_PROPERTY(PropertyInfo(Variant::QUAT, "rotation"), "set_rotation", "get_rotation"); // Quat + ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "rotation"), "set_rotation", "get_rotation"); // Quaternion ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale"), "set_scale", "get_scale"); // Vector3 ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "children"), "set_children", "get_children"); // Vector<int> ADD_PROPERTY(PropertyInfo(Variant::INT, "light"), "set_light", "get_light"); // GLTFLightIndex @@ -89,11 +89,11 @@ void GLTFNode::set_height(int p_height) { height = p_height; } -Transform GLTFNode::get_xform() { +Transform3D GLTFNode::get_xform() { return xform; } -void GLTFNode::set_xform(Transform p_xform) { +void GLTFNode::set_xform(Transform3D p_xform) { xform = p_xform; } @@ -145,11 +145,11 @@ void GLTFNode::set_translation(Vector3 p_translation) { translation = p_translation; } -Quat GLTFNode::get_rotation() { +Quaternion GLTFNode::get_rotation() { return rotation; } -void GLTFNode::set_rotation(Quat p_rotation) { +void GLTFNode::set_rotation(Quaternion p_rotation) { rotation = p_rotation; } diff --git a/modules/gltf/gltf_node.h b/modules/gltf/gltf_node.h index 3a5689d004..378b6da8bf 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/gltf_node.h @@ -43,14 +43,14 @@ private: // matrices need to be transformed to this GLTFNodeIndex parent = -1; int height = -1; - Transform xform; + Transform3D xform; GLTFMeshIndex mesh = -1; GLTFCameraIndex camera = -1; GLTFSkinIndex skin = -1; GLTFSkeletonIndex skeleton = -1; bool joint = false; Vector3 translation; - Quat rotation; + Quaternion rotation; Vector3 scale = Vector3(1, 1, 1); Vector<int> children; GLTFLightIndex light = -1; @@ -65,8 +65,8 @@ public: int get_height(); void set_height(int p_height); - Transform get_xform(); - void set_xform(Transform p_xform); + Transform3D get_xform(); + void set_xform(Transform3D p_xform); GLTFMeshIndex get_mesh(); void set_mesh(GLTFMeshIndex p_mesh); @@ -86,8 +86,8 @@ public: Vector3 get_translation(); void set_translation(Vector3 p_translation); - Quat get_rotation(); - void set_rotation(Quat p_rotation); + Quaternion get_rotation(); + void set_rotation(Quaternion p_rotation); Vector3 get_scale(); void set_scale(Vector3 p_scale); diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/gltf_skin.cpp index 5a61e5778c..5cf17135ac 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/gltf_skin.cpp @@ -54,7 +54,7 @@ void GLTFSkin::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "skin_root"), "set_skin_root", "get_skin_root"); // GLTFNodeIndex ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "joints_original"), "set_joints_original", "get_joints_original"); // Vector<GLTFNodeIndex> - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "inverse_binds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL), "set_inverse_binds", "get_inverse_binds"); // Vector<Transform> + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "inverse_binds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL), "set_inverse_binds", "get_inverse_binds"); // Vector<Transform3D> ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "joints"), "set_joints", "get_joints"); // Vector<GLTFNodeIndex> ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "non_joints"), "set_non_joints", "get_non_joints"); // Vector<GLTFNodeIndex> ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "roots"), "set_roots", "get_roots"); // Vector<GLTFNodeIndex> diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/gltf_skin.h index 7cc09d85bc..e32e2d397c 100644 --- a/modules/gltf/gltf_skin.h +++ b/modules/gltf/gltf_skin.h @@ -43,7 +43,7 @@ private: GLTFNodeIndex skin_root = -1; Vector<GLTFNodeIndex> joints_original; - Vector<Transform> inverse_binds; + Vector<Transform3D> inverse_binds; // Note: joints + non_joints should form a complete subtree, or subtrees // with a common parent diff --git a/modules/gridmap/config.py b/modules/gridmap/config.py index a6319fe1ea..720401b92d 100644 --- a/modules/gridmap/config.py +++ b/modules/gridmap/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 9b6fa138e5..fb0a2c9953 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -41,7 +41,7 @@ <return type="Array"> </return> <description> - Returns an array of [ArrayMesh]es and [Transform] references of all bake meshes that exist within the current GridMap. + Returns an array of [ArrayMesh]es and [Transform3D] references of all bake meshes that exist within the current GridMap. </description> </method> <method name="get_cell_item" qualifiers="const"> @@ -84,7 +84,7 @@ <return type="Array"> </return> <description> - Returns an array of [Transform] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. + Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. </description> </method> <method name="get_used_cells" qualifiers="const"> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index eaceaac33c..45af59622f 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -446,7 +446,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { * and set said multimesh bounding box to one containing all cells which have this item */ - Map<int, List<Pair<Transform, IndexKey>>> multimesh_items; + Map<int, List<Pair<Transform3D, IndexKey>>> multimesh_items; for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { ERR_CONTINUE(!cell_map.has(E->get())); @@ -459,7 +459,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z); Vector3 ofs = _get_offset(); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(c.rot); xform.set_origin(cellpos * cell_size + ofs); @@ -467,10 +467,10 @@ bool GridMap::_octant_update(const OctantKey &p_key) { if (baked_meshes.size() == 0) { if (mesh_library->get_item_mesh(c.item).is_valid()) { if (!multimesh_items.has(c.item)) { - multimesh_items[c.item] = List<Pair<Transform, IndexKey>>(); + multimesh_items[c.item] = List<Pair<Transform3D, IndexKey>>(); } - Pair<Transform, IndexKey> p; + Pair<Transform3D, IndexKey> p; p.first = xform; p.second = E->get(); multimesh_items[c.item].push_back(p); @@ -511,7 +511,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //update multimeshes, only if not baked if (baked_meshes.size() == 0) { - for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { + for (Map<int, List<Pair<Transform3D, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { Octant::MultimeshInstance mmi; RID mm = RS::get_singleton()->multimesh_create(); @@ -519,7 +519,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; - for (List<Pair<Transform, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) { + for (List<Pair<Transform3D, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) { RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first); #ifdef TOOLS_ENABLED @@ -672,7 +672,7 @@ void GridMap::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - Transform new_xform = get_global_transform(); + Transform3D new_xform = get_global_transform(); if (new_xform == last_transform) { break; } @@ -686,7 +686,6 @@ void GridMap::_notification(int p_what) { for (int i = 0; i < baked_meshes.size(); i++) { RS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform()); } - } break; case NOTIFICATION_EXIT_WORLD: { for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { @@ -934,7 +933,7 @@ Array GridMap::get_meshes() { Vector3 cellpos = Vector3(ik.x, ik.y, ik.z); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(E->get().rot); @@ -988,7 +987,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe Vector3 cellpos = Vector3(key.x, key.y, key.z); Vector3 ofs = _get_offset(); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(E->get().rot); xform.set_origin(cellpos * cell_size + ofs); @@ -1057,7 +1056,7 @@ Array GridMap::get_bake_meshes() { Array arr; for (int i = 0; i < baked_meshes.size(); i++) { arr.push_back(baked_meshes[i].mesh); - arr.push_back(Transform()); + arr.push_back(Transform3D()); } return arr; diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 4c04d492f7..8cd82e1f4c 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -89,7 +89,7 @@ class GridMap : public Node3D { struct Octant { struct NavMesh { RID region; - Transform xform; + Transform3D xform; }; struct MultimeshInstance { @@ -97,7 +97,7 @@ class GridMap : public Node3D { RID multimesh; struct Item { int index = 0; - Transform transform; + Transform3D transform; IndexKey key; }; @@ -137,7 +137,7 @@ class GridMap : public Node3D { bool bake_navigation = false; uint32_t navigation_layers = 1; - Transform last_transform; + Transform3D last_transform; bool _in_tree = false; Vector3 cell_size = Vector3(2, 2, 2); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 813b4b9689..a47ed6652d 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -255,7 +255,7 @@ void GridMapEditor::_menu_option(int p_option) { } void GridMapEditor::_update_cursor_transform() { - cursor_transform = Transform(); + cursor_transform = Transform3D(); cursor_transform.origin = cursor_origin; cursor_transform.basis.set_orthogonal_index(cursor_rot); cursor_transform.basis *= node->get_cell_scale(); @@ -268,7 +268,7 @@ void GridMapEditor::_update_cursor_transform() { } void GridMapEditor::_update_selection_transform() { - Transform xf_zero; + Transform3D xf_zero; xf_zero.basis.set_zero(); if (!selection.active) { @@ -279,7 +279,7 @@ void GridMapEditor::_update_selection_transform() { return; } - Transform xf; + Transform3D xf; xf.scale((Vector3(1, 1, 1) + (selection.end - selection.begin)) * node->get_cell_size()); xf.origin = selection.begin * node->get_cell_size(); @@ -297,7 +297,7 @@ void GridMapEditor::_update_selection_transform() { scale *= node->get_cell_size(); position *= node->get_cell_size(); - Transform xf2; + Transform3D xf2; xf2.basis.scale(scale); xf2.origin = position; @@ -362,7 +362,7 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b Camera3D *camera = p_camera; Vector3 from = camera->project_ray_origin(p_point); Vector3 normal = camera->project_ray_normal(p_point); - Transform local_xform = node->get_global_transform().affine_inverse(); + Transform3D local_xform = node->get_global_transform().affine_inverse(); Vector<Plane> planes = camera->get_frustum(); from = local_xform.xform(from); normal = local_xform.basis.xform(normal).normalized(); @@ -540,7 +540,7 @@ void GridMapEditor::_set_clipboard_data() { void GridMapEditor::_update_paste_indicator() { if (input_action != INPUT_PASTE) { - Transform xf; + Transform3D xf; xf.basis.set_zero(); RenderingServer::get_singleton()->instance_set_transform(paste_instance, xf); return; @@ -548,7 +548,7 @@ void GridMapEditor::_update_paste_indicator() { Vector3 center = 0.5 * Vector3(real_t(node->get_center_x()), real_t(node->get_center_y()), real_t(node->get_center_z())); Vector3 scale = (Vector3(1, 1, 1) + (paste_indicator.end - paste_indicator.begin)) * node->get_cell_size(); - Transform xf; + Transform3D xf; xf.scale(scale); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); Basis rot; @@ -561,7 +561,7 @@ void GridMapEditor::_update_paste_indicator() { for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { ClipboardItem &item = E->get(); - xf = Transform(); + xf = Transform3D(); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); xf.basis = rot * xf.basis; xf.translate(item.grid_offset * node->get_cell_size()); @@ -1068,7 +1068,7 @@ void GridMapEditor::_notification(int p_what) { return; } - Transform xf = node->get_global_transform(); + Transform3D xf = node->get_global_transform(); if (xf != grid_xform) { for (int i = 0; i < 3; i++) { diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 6c7f0bedf6..0e29c88d26 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -95,8 +95,8 @@ class GridMapEditor : public VBoxContainer { ClipMode clip_mode = CLIP_DISABLED; bool lock_view = false; - Transform grid_xform; - Transform edit_grid_xform; + Transform3D grid_xform; + Transform3D edit_grid_xform; Vector3::Axis edit_axis; int edit_floor[3]; Vector3 grid_ofs; @@ -146,7 +146,7 @@ class GridMapEditor : public VBoxContainer { PasteIndicator paste_indicator; bool cursor_visible = false; - Transform cursor_transform; + Transform3D cursor_transform; Vector3 cursor_origin; diff --git a/modules/meshoptimizer/config.py b/modules/meshoptimizer/config.py index 82e4e43397..b7e69569b9 100644 --- a/modules/meshoptimizer/config.py +++ b/modules/meshoptimizer/config.py @@ -1,6 +1,6 @@ def can_build(env, platform): # Having this on release by default, it's small and a lot of users like to do procedural stuff - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/mobile_vr/config.py b/modules/mobile_vr/config.py index ee401c1a2a..f6b64fb690 100644 --- a/modules/mobile_vr/config.py +++ b/modules/mobile_vr/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 5140cfbbaf..40b1745c35 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -185,8 +185,8 @@ void MobileVRInterface::set_position_from_sensors() { // if you have a gyro + accelerometer that combo tends to be better than combining all three but without a gyro you need the magnetometer.. if (has_magneto && has_grav && !has_gyro) { // convert to quaternions, easier to smooth those out - Quat transform_quat(orientation); - Quat acc_mag_quat(combine_acc_mag(grav, magneto)); + Quaternion transform_quat(orientation); + Quaternion acc_mag_quat(combine_acc_mag(grav, magneto)); transform_quat = transform_quat.slerp(acc_mag_quat, 0.1); orientation = Basis(transform_quat); @@ -361,10 +361,10 @@ Size2 MobileVRInterface::get_render_targetsize() { return target_size; }; -Transform MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { +Transform3D MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) { _THREAD_SAFE_METHOD_ - Transform transform_for_eye; + Transform3D transform_for_eye; XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, transform_for_eye); @@ -383,7 +383,7 @@ Transform MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, cons }; // just scale our origin point of our transform - Transform hmd_transform; + Transform3D hmd_transform; hmd_transform.basis = orientation; hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index d28c2196af..aad40ebb5b 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -139,7 +139,7 @@ public: virtual Size2 get_render_targetsize() override; virtual bool is_stereo() override; - virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) override; + virtual Transform3D get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) override; virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) override; virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) override; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b6a7a7579c..ac248bcff8 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -496,10 +496,10 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::VECTOR3I, Variant::TRANSFORM2D, Variant::PLANE, - Variant::QUAT, + Variant::QUATERNION, Variant::AABB, Variant::BASIS, - Variant::TRANSFORM, + Variant::TRANSFORM3D, Variant::COLOR, Variant::STRING_NAME, Variant::NODE_PATH, @@ -2105,46 +2105,10 @@ bool CSharpInstance::refcount_decremented() { return ref_dying; } -Vector<ScriptNetData> CSharpInstance::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> CSharpInstance::get_rpc_methods() const { return script->get_rpc_methods(); } -uint16_t CSharpInstance::get_rpc_method_id(const StringName &p_method) const { - return script->get_rpc_method_id(p_method); -} - -StringName CSharpInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { - return script->get_rpc_method(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - return script->get_rpc_mode_by_id(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const { - return script->get_rpc_mode(p_method); -} - -Vector<ScriptNetData> CSharpInstance::get_rset_properties() const { - return script->get_rset_properties(); -} - -uint16_t CSharpInstance::get_rset_property_id(const StringName &p_variable) const { - return script->get_rset_property_id(p_variable); -} - -StringName CSharpInstance::get_rset_property(const uint16_t p_rset_member_id) const { - return script->get_rset_property(p_rset_member_id); -} - -MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - return script->get_rset_mode_by_id(p_rset_member_id); -} - -MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const { - return script->get_rset_mode(p_variable); -} - void CSharpInstance::notification(int p_notification) { GD_MONO_SCOPE_THREAD_ATTACH; @@ -3046,7 +3010,6 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); p_script->rpc_functions.clear(); - p_script->rpc_variables.clear(); GDMonoClass *top = p_script->script_class; while (top && top != p_script->native) { @@ -3060,9 +3023,12 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { if (!methods[i]->is_static()) { MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(methods[i]); if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { - ScriptNetData nd; + MultiplayerAPI::RPCConfig nd; nd.name = methods[i]->get_name(); - nd.mode = mode; + nd.rpc_mode = mode; + // TODO Transfer mode, channel + nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; + nd.channel = 0; if (-1 == p_script->rpc_functions.find(nd)) { p_script->rpc_functions.push_back(nd); } @@ -3071,46 +3037,11 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { } } - { - Vector<GDMonoField *> fields = top->get_all_fields(); - for (int i = 0; i < fields.size(); i++) { - if (!fields[i]->is_static()) { - MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(fields[i]); - if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { - ScriptNetData nd; - nd.name = fields[i]->get_name(); - nd.mode = mode; - if (-1 == p_script->rpc_variables.find(nd)) { - p_script->rpc_variables.push_back(nd); - } - } - } - } - } - - { - Vector<GDMonoProperty *> properties = top->get_all_properties(); - for (int i = 0; i < properties.size(); i++) { - if (!properties[i]->is_static()) { - MultiplayerAPI::RPCMode mode = p_script->_member_get_rpc_mode(properties[i]); - if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { - ScriptNetData nd; - nd.name = properties[i]->get_name(); - nd.mode = mode; - if (-1 == p_script->rpc_variables.find(nd)) { - p_script->rpc_variables.push_back(nd); - } - } - } - } - } - top = top->get_parent_class(); } // Sort so we are 100% that they are always the same. - p_script->rpc_functions.sort_custom<SortNetData>(); - p_script->rpc_variables.sort_custom<SortNetData>(); + p_script->rpc_functions.sort_custom<MultiplayerAPI::SortRPCConfig>(); p_script->load_script_signals(p_script->script_class, p_script->native); } @@ -3543,60 +3474,10 @@ MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_m return MultiplayerAPI::RPC_MODE_DISABLED; } -Vector<ScriptNetData> CSharpScript::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> CSharpScript::get_rpc_methods() const { return rpc_functions; } -uint16_t CSharpScript::get_rpc_method_id(const StringName &p_method) const { - for (int i = 0; i < rpc_functions.size(); i++) { - if (rpc_functions[i].name == p_method) { - return i; - } - } - return UINT16_MAX; -} - -StringName CSharpScript::get_rpc_method(const uint16_t p_rpc_method_id) const { - ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName()); - return rpc_functions[p_rpc_method_id].name; -} - -MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_functions[p_rpc_method_id].mode; -} - -MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode(const StringName &p_method) const { - return get_rpc_mode_by_id(get_rpc_method_id(p_method)); -} - -Vector<ScriptNetData> CSharpScript::get_rset_properties() const { - return rpc_variables; -} - -uint16_t CSharpScript::get_rset_property_id(const StringName &p_variable) const { - for (int i = 0; i < rpc_variables.size(); i++) { - if (rpc_variables[i].name == p_variable) { - return i; - } - } - return UINT16_MAX; -} - -StringName CSharpScript::get_rset_property(const uint16_t p_rset_member_id) const { - ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName()); - return rpc_variables[p_rset_member_id].name; -} - -MultiplayerAPI::RPCMode CSharpScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { - ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_functions[p_rset_member_id].mode; -} - -MultiplayerAPI::RPCMode CSharpScript::get_rset_mode(const StringName &p_variable) const { - return get_rset_mode_by_id(get_rset_property_id(p_variable)); -} - Error CSharpScript::load_source_code(const String &p_path) { Error ferr = read_all_file_utf8(p_path, source); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 992c7e93c8..b389e900f4 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -136,8 +136,7 @@ private: Map<StringName, EventSignal> event_signals; bool signals_invalidated = true; - Vector<ScriptNetData> rpc_functions; - Vector<ScriptNetData> rpc_variables; + Vector<MultiplayerAPI::RPCConfig> rpc_functions; #ifdef TOOLS_ENABLED List<PropertyInfo> exported_members_cache; // members_cache @@ -235,17 +234,7 @@ public: int get_member_line(const StringName &p_member) const override; - Vector<ScriptNetData> get_rpc_methods() const override; - uint16_t get_rpc_method_id(const StringName &p_method) const override; - StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; - MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - Vector<ScriptNetData> get_rset_properties() const override; - uint16_t get_rset_property_id(const StringName &p_variable) const override; - StringName get_rset_property(const uint16_t p_variable_id) const override; - MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override; - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; #ifdef TOOLS_ENABLED bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -322,17 +311,7 @@ public: void refcount_incremented() override; bool refcount_decremented() override; - Vector<ScriptNetData> get_rpc_methods() const override; - uint16_t get_rpc_method_id(const StringName &p_method) const override; - StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; - MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - Vector<ScriptNetData> get_rset_properties() const override; - uint16_t get_rset_property_id(const StringName &p_variable) const override; - StringName get_rset_property(const uint16_t p_variable_id) const override; - MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override; - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; void notification(int p_notification) override; void _call_notification(int p_notification); @@ -470,7 +449,7 @@ public: /* EDITOR FUNCTIONS */ void get_reserved_words(List<String> *p_words) const override; - bool is_control_flow_keyword(String p_keyword) const; + bool is_control_flow_keyword(String p_keyword) const override; void get_comment_delimiters(List<String> *p_delimiters) const override; void get_string_delimiters(List<String> *p_delimiters) const override; Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index b48e5df9eb..94c5195b83 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2520,10 +2520,10 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & p_arg_type.name == name_cache.type_NodePath; case Variant::NODE_PATH: return p_arg_type.name == name_cache.type_NodePath; - case Variant::TRANSFORM: case Variant::TRANSFORM2D: + case Variant::TRANSFORM3D: case Variant::BASIS: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::PLANE: case Variant::AABB: case Variant::COLOR: @@ -3123,13 +3123,13 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; - case Variant::TRANSFORM: { - Transform transform = p_val.operator Transform(); - if (transform == Transform()) { - r_iarg.default_argument = "Transform.Identity"; + case Variant::TRANSFORM3D: { + Transform3D transform = p_val.operator Transform3D(); + if (transform == Transform3D()) { + r_iarg.default_argument = "Transform3D.Identity"; } else { Basis basis = transform.basis; - r_iarg.default_argument = "new Transform(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")"; + r_iarg.default_argument = "new Transform3D(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -3142,12 +3142,12 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; - case Variant::QUAT: { - Quat quat = p_val.operator Quat(); - if (quat == Quat()) { - r_iarg.default_argument = "Quat.Identity"; + case Variant::QUATERNION: { + Quaternion quaternion = p_val.operator Quaternion(); + if (quaternion == Quaternion()) { + r_iarg.default_argument = "Quaternion.Identity"; } else { - r_iarg.default_argument = "new Quat" + quat.operator String(); + r_iarg.default_argument = "new Quaternion" + quaternion.operator String(); } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -3196,8 +3196,8 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { INSERT_STRUCT_TYPE(Vector3) INSERT_STRUCT_TYPE(Vector3i) INSERT_STRUCT_TYPE(Basis) - INSERT_STRUCT_TYPE(Quat) - INSERT_STRUCT_TYPE(Transform) + INSERT_STRUCT_TYPE(Quaternion) + INSERT_STRUCT_TYPE(Transform3D) INSERT_STRUCT_TYPE(AABB) INSERT_STRUCT_TYPE(Color) INSERT_STRUCT_TYPE(Plane) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 3f1120575f..01525e593f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -207,7 +207,7 @@ namespace Godot } } - public Quat RotationQuat() + public Quaternion RotationQuaternion() { Basis orthonormalizedBasis = Orthonormalized(); real_t det = orthonormalizedBasis.Determinant(); @@ -218,18 +218,18 @@ namespace Godot orthonormalizedBasis = orthonormalizedBasis.Scaled(-Vector3.One); } - return orthonormalizedBasis.Quat(); + return orthonormalizedBasis.Quaternion(); } - internal void SetQuatScale(Quat quat, Vector3 scale) + internal void SetQuaternionScale(Quaternion quaternion, Vector3 scale) { SetDiagonal(scale); - Rotate(quat); + Rotate(quaternion); } - private void Rotate(Quat quat) + private void Rotate(Quaternion quaternion) { - this *= new Basis(quat); + this *= new Basis(quaternion); } private void SetDiagonal(Vector3 diagonal) @@ -263,8 +263,8 @@ namespace Godot /// The returned vector contains the rotation angles in /// the format (X angle, Y angle, Z angle). /// - /// Consider using the <see cref="Basis.Quat()"/> method instead, which - /// returns a <see cref="Godot.Quat"/> quaternion instead of Euler angles. + /// Consider using the <see cref="Basis.Quaternion()"/> method instead, which + /// returns a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles. /// </summary> /// <returns>A Vector3 representing the basis rotation in Euler angles.</returns> public Vector3 GetEuler() @@ -486,8 +486,8 @@ namespace Godot /// <returns>The resulting basis matrix of the interpolation.</returns> public Basis Slerp(Basis target, real_t weight) { - Quat from = new Quat(this); - Quat to = new Quat(target); + Quaternion from = new Quaternion(this); + Quaternion to = new Quaternion(target); Basis b = new Basis(from.Slerp(to, weight)); b.Row0 *= Mathf.Lerp(Row0.Length(), target.Row0.Length(), weight); @@ -588,8 +588,8 @@ namespace Godot /// See <see cref="GetEuler()"/> if you need Euler angles, but keep in /// mind that quaternions should generally be preferred to Euler angles. /// </summary> - /// <returns>A <see cref="Godot.Quat"/> representing the basis's rotation.</returns> - public Quat Quat() + /// <returns>A <see cref="Godot.Quaternion"/> representing the basis's rotation.</returns> + public Quaternion Quaternion() { real_t trace = Row0[0] + Row1[1] + Row2[2]; @@ -597,7 +597,7 @@ namespace Godot { real_t s = Mathf.Sqrt(trace + 1.0f) * 2f; real_t inv_s = 1f / s; - return new Quat( + return new Quaternion( (Row2[1] - Row1[2]) * inv_s, (Row0[2] - Row2[0]) * inv_s, (Row1[0] - Row0[1]) * inv_s, @@ -609,7 +609,7 @@ namespace Godot { real_t s = Mathf.Sqrt(Row0[0] - Row1[1] - Row2[2] + 1.0f) * 2f; real_t inv_s = 1f / s; - return new Quat( + return new Quaternion( s * 0.25f, (Row0[1] + Row1[0]) * inv_s, (Row0[2] + Row2[0]) * inv_s, @@ -621,7 +621,7 @@ namespace Godot { real_t s = Mathf.Sqrt(-Row0[0] + Row1[1] - Row2[2] + 1.0f) * 2f; real_t inv_s = 1f / s; - return new Quat( + return new Quaternion( (Row0[1] + Row1[0]) * inv_s, s * 0.25f, (Row1[2] + Row2[1]) * inv_s, @@ -632,7 +632,7 @@ namespace Godot { real_t s = Mathf.Sqrt(-Row0[0] - Row1[1] + Row2[2] + 1.0f) * 2f; real_t inv_s = 1f / s; - return new Quat( + return new Quaternion( (Row0[2] + Row2[0]) * inv_s, (Row1[2] + Row2[1]) * inv_s, s * 0.25f, @@ -699,23 +699,23 @@ namespace Godot /// <summary> /// Constructs a pure rotation basis matrix from the given quaternion. /// </summary> - /// <param name="quat">The quaternion to create the basis from.</param> - public Basis(Quat quat) + /// <param name="quaternion">The quaternion to create the basis from.</param> + public Basis(Quaternion quaternion) { - real_t s = 2.0f / quat.LengthSquared; + real_t s = 2.0f / quaternion.LengthSquared; - real_t xs = quat.x * s; - real_t ys = quat.y * s; - real_t zs = quat.z * s; - real_t wx = quat.w * xs; - real_t wy = quat.w * ys; - real_t wz = quat.w * zs; - real_t xx = quat.x * xs; - real_t xy = quat.x * ys; - real_t xz = quat.x * zs; - real_t yy = quat.y * ys; - real_t yz = quat.y * zs; - real_t zz = quat.z * zs; + real_t xs = quaternion.x * s; + real_t ys = quaternion.y * s; + real_t zs = quaternion.z * s; + real_t wx = quaternion.w * xs; + real_t wy = quaternion.w * ys; + real_t wz = quaternion.w * zs; + real_t xx = quaternion.x * xs; + real_t xy = quaternion.x * ys; + real_t xz = quaternion.x * zs; + real_t yy = quaternion.y * ys; + real_t yz = quaternion.y * zs; + real_t zz = quaternion.z * zs; Row0 = new Vector3(1.0f - (yy + zz), xy - wz, xz + wy); Row1 = new Vector3(xy + wz, 1.0f - (xx + zz), yz - wx); @@ -727,8 +727,8 @@ namespace Godot /// (in the YXZ convention: when *composing*, first Y, then X, and Z last), /// given in the vector format as (X angle, Y angle, Z angle). /// - /// Consider using the <see cref="Basis(Quat)"/> constructor instead, which - /// uses a <see cref="Godot.Quat"/> quaternion instead of Euler angles. + /// Consider using the <see cref="Basis(Quaternion)"/> constructor instead, which + /// uses a <see cref="Godot.Quaternion"/> quaternion instead of Euler angles. /// </summary> /// <param name="eulerYXZ">The Euler angles to create the basis from.</param> public Basis(Vector3 eulerYXZ) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 2a9f834aac..24b9218197 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -257,6 +257,27 @@ namespace Godot } /// <summary> + /// Returns a new color with all components clamped between the + /// components of `min` and `max` using + /// <see cref="Mathf.Clamp(float, float, float)"/>. + /// </summary> + /// <param name="min">The color with minimum allowed values.</param> + /// <param name="max">The color with maximum allowed values.</param> + /// <returns>The color with all components clamped.</returns> + public Color Clamp(Color? min = null, Color? max = null) + { + Color minimum = min ?? new Color(0, 0, 0, 0); + Color maximum = max ?? new Color(1, 1, 1, 1); + return new Color + ( + (float)Mathf.Clamp(r, minimum.r, maximum.r), + (float)Mathf.Clamp(g, minimum.g, maximum.g), + (float)Mathf.Clamp(b, minimum.b, maximum.b), + (float)Mathf.Clamp(a, minimum.a, maximum.a) + ); + } + + /// <summary> /// Returns a new color resulting from making this color darker /// by the specified ratio (on the range of 0 to 1). /// </summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index bd3bcb0c58..b087b4c200 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -15,7 +15,7 @@ namespace Godot /// It is similar to Basis, which implements matrix representation of /// rotations, and can be parametrized using both an axis-angle pair /// or Euler angles. Basis stores rotation, scale, and shearing, - /// while Quat only stores rotation. + /// while Quaternion only stores rotation. /// /// Due to its compactness and the way it is stored in memory, certain /// operations (obtaining axis-angle and performing SLERP, in particular) @@ -23,7 +23,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Quat : IEquatable<Quat> + public struct Quaternion : IEquatable<Quaternion> { /// <summary> /// X component of the quaternion (imaginary `i` axis part). @@ -122,11 +122,11 @@ namespace Godot /// <param name="postB">A quaternion after `b`.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The interpolated quaternion.</returns> - public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t weight) + public Quaternion CubicSlerp(Quaternion b, Quaternion preA, Quaternion postB, real_t weight) { real_t t2 = (1.0f - weight) * weight * 2f; - Quat sp = Slerp(b, weight); - Quat sq = preA.Slerpni(postB, weight); + Quaternion sp = Slerp(b, weight); + Quaternion sq = preA.Slerpni(postB, weight); return sp.Slerpni(sq, t2); } @@ -135,7 +135,7 @@ namespace Godot /// </summary> /// <param name="b">The other quaternion.</param> /// <returns>The dot product.</returns> - public real_t Dot(Quat b) + public real_t Dot(Quaternion b) { return x * b.x + y * b.y + z * b.z + w * b.w; } @@ -152,7 +152,7 @@ namespace Godot #if DEBUG if (!IsNormalized()) { - throw new InvalidOperationException("Quat is not normalized"); + throw new InvalidOperationException("Quaternion is not normalized"); } #endif var basis = new Basis(this); @@ -163,15 +163,15 @@ namespace Godot /// Returns the inverse of the quaternion. /// </summary> /// <returns>The inverse quaternion.</returns> - public Quat Inverse() + public Quaternion Inverse() { #if DEBUG if (!IsNormalized()) { - throw new InvalidOperationException("Quat is not normalized"); + throw new InvalidOperationException("Quaternion is not normalized"); } #endif - return new Quat(-x, -y, -z, w); + return new Quaternion(-x, -y, -z, w); } /// <summary> @@ -187,7 +187,7 @@ namespace Godot /// Returns a copy of the quaternion, normalized to unit length. /// </summary> /// <returns>The normalized quaternion.</returns> - public Quat Normalized() + public Quaternion Normalized() { return this / Length; } @@ -201,12 +201,12 @@ namespace Godot /// <param name="to">The destination quaternion for interpolation. Must be normalized.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting quaternion of the interpolation.</returns> - public Quat Slerp(Quat to, real_t weight) + public Quaternion Slerp(Quaternion to, real_t weight) { #if DEBUG if (!IsNormalized()) { - throw new InvalidOperationException("Quat is not normalized"); + throw new InvalidOperationException("Quaternion is not normalized"); } if (!to.IsNormalized()) { @@ -217,7 +217,7 @@ namespace Godot // Calculate cosine. real_t cosom = x * to.x + y * to.y + z * to.z + w * to.w; - var to1 = new Quat(); + var to1 = new Quaternion(); // Adjust signs if necessary. if (cosom < 0.0) @@ -255,7 +255,7 @@ namespace Godot } // Calculate final values. - return new Quat + return new Quaternion ( scale0 * x + scale1 * to1.x, scale0 * y + scale1 * to1.y, @@ -272,7 +272,7 @@ namespace Godot /// <param name="to">The destination quaternion for interpolation. Must be normalized.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting quaternion of the interpolation.</returns> - public Quat Slerpni(Quat to, real_t weight) + public Quaternion Slerpni(Quaternion to, real_t weight) { real_t dot = Dot(to); @@ -286,7 +286,7 @@ namespace Godot real_t newFactor = Mathf.Sin(weight * theta) * sinT; real_t invFactor = Mathf.Sin((1.0f - weight) * theta) * sinT; - return new Quat + return new Quaternion ( invFactor * x + newFactor * to.x, invFactor * y + newFactor * to.y, @@ -305,7 +305,7 @@ namespace Godot #if DEBUG if (!IsNormalized()) { - throw new InvalidOperationException("Quat is not normalized"); + throw new InvalidOperationException("Quaternion is not normalized"); } #endif var u = new Vector3(x, y, z); @@ -314,15 +314,15 @@ namespace Godot } // Constants - private static readonly Quat _identity = new Quat(0, 0, 0, 1); + private static readonly Quaternion _identity = new Quaternion(0, 0, 0, 1); /// <summary> /// The identity quaternion, representing no rotation. /// Equivalent to an identity <see cref="Basis"/> matrix. If a vector is transformed by /// an identity quaternion, it will not change. /// </summary> - /// <value>Equivalent to `new Quat(0, 0, 0, 1)`.</value> - public static Quat Identity { get { return _identity; } } + /// <value>Equivalent to `new Quaternion(0, 0, 0, 1)`.</value> + public static Quaternion Identity { get { return _identity; } } /// <summary> /// Constructs a quaternion defined by the given values. @@ -331,7 +331,7 @@ namespace Godot /// <param name="y">Y component of the quaternion (imaginary `j` axis part).</param> /// <param name="z">Z component of the quaternion (imaginary `k` axis part).</param> /// <param name="w">W component of the quaternion (real part).</param> - public Quat(real_t x, real_t y, real_t z, real_t w) + public Quaternion(real_t x, real_t y, real_t z, real_t w) { this.x = x; this.y = y; @@ -343,7 +343,7 @@ namespace Godot /// Constructs a quaternion from the given quaternion. /// </summary> /// <param name="q">The existing quaternion.</param> - public Quat(Quat q) + public Quaternion(Quaternion q) { this = q; } @@ -352,9 +352,9 @@ namespace Godot /// Constructs a quaternion from the given <see cref="Basis"/>. /// </summary> /// <param name="basis">The basis to construct from.</param> - public Quat(Basis basis) + public Quaternion(Basis basis) { - this = basis.Quat(); + this = basis.Quaternion(); } /// <summary> @@ -364,7 +364,7 @@ namespace Godot /// given in the vector format as (X angle, Y angle, Z angle). /// </summary> /// <param name="eulerYXZ"></param> - public Quat(Vector3 eulerYXZ) + public Quaternion(Vector3 eulerYXZ) { real_t half_a1 = eulerYXZ.y * 0.5f; real_t half_a2 = eulerYXZ.x * 0.5f; @@ -393,7 +393,7 @@ namespace Godot /// </summary> /// <param name="axis">The axis to rotate around. Must be normalized.</param> /// <param name="angle">The angle to rotate, in radians.</param> - public Quat(Vector3 axis, real_t angle) + public Quaternion(Vector3 axis, real_t angle) { #if DEBUG if (!axis.IsNormalized()) @@ -424,9 +424,9 @@ namespace Godot } } - public static Quat operator *(Quat left, Quat right) + public static Quaternion operator *(Quaternion left, Quaternion right) { - return new Quat + return new Quaternion ( left.w * right.x + left.x * right.w + left.y * right.z - left.z * right.y, left.w * right.y + left.y * right.w + left.z * right.x - left.x * right.z, @@ -435,24 +435,24 @@ namespace Godot ); } - public static Quat operator +(Quat left, Quat right) + public static Quaternion operator +(Quaternion left, Quaternion right) { - return new Quat(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + return new Quaternion(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); } - public static Quat operator -(Quat left, Quat right) + public static Quaternion operator -(Quaternion left, Quaternion right) { - return new Quat(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + return new Quaternion(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); } - public static Quat operator -(Quat left) + public static Quaternion operator -(Quaternion left) { - return new Quat(-left.x, -left.y, -left.z, -left.w); + return new Quaternion(-left.x, -left.y, -left.z, -left.w); } - public static Quat operator *(Quat left, Vector3 right) + public static Quaternion operator *(Quaternion left, Vector3 right) { - return new Quat + return new Quaternion ( left.w * right.x + left.y * right.z - left.z * right.y, left.w * right.y + left.z * right.x - left.x * right.z, @@ -461,9 +461,9 @@ namespace Godot ); } - public static Quat operator *(Vector3 left, Quat right) + public static Quaternion operator *(Vector3 left, Quaternion right) { - return new Quat + return new Quaternion ( right.w * left.x + right.y * left.z - right.z * left.y, right.w * left.y + right.z * left.x - right.x * left.z, @@ -472,42 +472,42 @@ namespace Godot ); } - public static Quat operator *(Quat left, real_t right) + public static Quaternion operator *(Quaternion left, real_t right) { - return new Quat(left.x * right, left.y * right, left.z * right, left.w * right); + return new Quaternion(left.x * right, left.y * right, left.z * right, left.w * right); } - public static Quat operator *(real_t left, Quat right) + public static Quaternion operator *(real_t left, Quaternion right) { - return new Quat(right.x * left, right.y * left, right.z * left, right.w * left); + return new Quaternion(right.x * left, right.y * left, right.z * left, right.w * left); } - public static Quat operator /(Quat left, real_t right) + public static Quaternion operator /(Quaternion left, real_t right) { return left * (1.0f / right); } - public static bool operator ==(Quat left, Quat right) + public static bool operator ==(Quaternion left, Quaternion right) { return left.Equals(right); } - public static bool operator !=(Quat left, Quat right) + public static bool operator !=(Quaternion left, Quaternion right) { return !left.Equals(right); } public override bool Equals(object obj) { - if (obj is Quat) + if (obj is Quaternion) { - return Equals((Quat)obj); + return Equals((Quaternion)obj); } return false; } - public bool Equals(Quat other) + public bool Equals(Quaternion other) { return x == other.x && y == other.y && z == other.z && w == other.w; } @@ -518,7 +518,7 @@ namespace Godot /// </summary> /// <param name="other">The other quaternion to compare.</param> /// <returns>Whether or not the quaternions are approximately equal.</returns> - public bool IsEqualApprox(Quat other) + public bool IsEqualApprox(Quaternion other) { return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index ac47f6029f..50cc95fb95 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -19,7 +19,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Transform : IEquatable<Transform> + public struct Transform3D : IEquatable<Transform3D> { /// <summary> /// The <see cref="Basis"/> of this transform. Contains the X, Y, and Z basis @@ -107,10 +107,10 @@ namespace Godot /// the transformation is composed of rotation, scaling, and translation. /// </summary> /// <returns>The inverse transformation matrix.</returns> - public Transform AffineInverse() + public Transform3D AffineInverse() { Basis basisInv = basis.Inverse(); - return new Transform(basisInv, basisInv.Xform(-origin)); + return new Transform3D(basisInv, basisInv.Xform(-origin)); } /// <summary> @@ -119,20 +119,20 @@ namespace Godot /// <param name="transform">The other transform.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The interpolated transform.</returns> - public Transform InterpolateWith(Transform transform, real_t weight) + public Transform3D InterpolateWith(Transform3D transform, real_t weight) { /* not sure if very "efficient" but good enough? */ Vector3 sourceScale = basis.Scale; - Quat sourceRotation = basis.RotationQuat(); + Quaternion sourceRotation = basis.RotationQuaternion(); Vector3 sourceLocation = origin; Vector3 destinationScale = transform.basis.Scale; - Quat destinationRotation = transform.basis.RotationQuat(); + Quaternion destinationRotation = transform.basis.RotationQuaternion(); Vector3 destinationLocation = transform.origin; - var interpolated = new Transform(); - interpolated.basis.SetQuatScale(sourceRotation.Slerp(destinationRotation, weight).Normalized(), sourceScale.Lerp(destinationScale, weight)); + var interpolated = new Transform3D(); + interpolated.basis.SetQuaternionScale(sourceRotation.Slerp(destinationRotation, weight).Normalized(), sourceScale.Lerp(destinationScale, weight)); interpolated.origin = sourceLocation.Lerp(destinationLocation, weight); return interpolated; @@ -144,10 +144,10 @@ namespace Godot /// (no scaling, use <see cref="AffineInverse"/> for transforms with scaling). /// </summary> /// <returns>The inverse matrix.</returns> - public Transform Inverse() + public Transform3D Inverse() { Basis basisTr = basis.Transposed(); - return new Transform(basisTr, basisTr.Xform(-origin)); + return new Transform3D(basisTr, basisTr.Xform(-origin)); } /// <summary> @@ -163,7 +163,7 @@ namespace Godot /// <param name="target">The object to look at.</param> /// <param name="up">The relative up direction</param> /// <returns>The resulting transform.</returns> - public Transform LookingAt(Vector3 target, Vector3 up) + public Transform3D LookingAt(Vector3 target, Vector3 up) { var t = this; t.SetLookAt(origin, target, up); @@ -175,9 +175,9 @@ namespace Godot /// and normalized axis vectors (scale of 1 or -1). /// </summary> /// <returns>The orthonormalized transform.</returns> - public Transform Orthonormalized() + public Transform3D Orthonormalized() { - return new Transform(basis.Orthonormalized(), origin); + return new Transform3D(basis.Orthonormalized(), origin); } /// <summary> @@ -187,9 +187,9 @@ namespace Godot /// <param name="axis">The axis to rotate around. Must be normalized.</param> /// <param name="phi">The angle to rotate, in radians.</param> /// <returns>The rotated transformation matrix.</returns> - public Transform Rotated(Vector3 axis, real_t phi) + public Transform3D Rotated(Vector3 axis, real_t phi) { - return new Transform(new Basis(axis, phi), new Vector3()) * this; + return new Transform3D(new Basis(axis, phi), new Vector3()) * this; } /// <summary> @@ -197,9 +197,9 @@ namespace Godot /// </summary> /// <param name="scale">The scale to introduce.</param> /// <returns>The scaled transformation matrix.</returns> - public Transform Scaled(Vector3 scale) + public Transform3D Scaled(Vector3 scale) { - return new Transform(basis.Scaled(scale), origin * scale); + return new Transform3D(basis.Scaled(scale), origin * scale); } private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up) @@ -234,9 +234,9 @@ namespace Godot /// </summary> /// <param name="offset">The offset to translate by.</param> /// <returns>The translated matrix.</returns> - public Transform Translated(Vector3 offset) + public Transform3D Translated(Vector3 offset) { - return new Transform(basis, new Vector3 + return new Transform3D(basis, new Vector3 ( origin[0] += basis.Row0.Dot(offset), origin[1] += basis.Row1.Dot(offset), @@ -280,10 +280,10 @@ namespace Godot } // Constants - private static readonly Transform _identity = new Transform(Basis.Identity, Vector3.Zero); - private static readonly Transform _flipX = new Transform(new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1), Vector3.Zero); - private static readonly Transform _flipY = new Transform(new Basis(1, 0, 0, 0, -1, 0, 0, 0, 1), Vector3.Zero); - private static readonly Transform _flipZ = new Transform(new Basis(1, 0, 0, 0, 1, 0, 0, 0, -1), Vector3.Zero); + private static readonly Transform3D _identity = new Transform3D(Basis.Identity, Vector3.Zero); + private static readonly Transform3D _flipX = new Transform3D(new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1), Vector3.Zero); + private static readonly Transform3D _flipY = new Transform3D(new Basis(1, 0, 0, 0, -1, 0, 0, 0, 1), Vector3.Zero); + private static readonly Transform3D _flipZ = new Transform3D(new Basis(1, 0, 0, 0, 1, 0, 0, 0, -1), Vector3.Zero); /// <summary> /// The identity transform, with no translation, rotation, or scaling applied. @@ -291,22 +291,22 @@ namespace Godot /// Do not use `new Transform()` with no arguments in C#, because it sets all values to zero. /// </summary> /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Up, Vector3.Back, Vector3.Zero)`.</value> - public static Transform Identity { get { return _identity; } } + public static Transform3D Identity { get { return _identity; } } /// <summary> /// The transform that will flip something along the X axis. /// </summary> /// <value>Equivalent to `new Transform(Vector3.Left, Vector3.Up, Vector3.Back, Vector3.Zero)`.</value> - public static Transform FlipX { get { return _flipX; } } + public static Transform3D FlipX { get { return _flipX; } } /// <summary> /// The transform that will flip something along the Y axis. /// </summary> /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Down, Vector3.Back, Vector3.Zero)`.</value> - public static Transform FlipY { get { return _flipY; } } + public static Transform3D FlipY { get { return _flipY; } } /// <summary> /// The transform that will flip something along the Z axis. /// </summary> /// <value>Equivalent to `new Transform(Vector3.Right, Vector3.Up, Vector3.Forward, Vector3.Zero)`.</value> - public static Transform FlipZ { get { return _flipZ; } } + public static Transform3D FlipZ { get { return _flipZ; } } /// <summary> /// Constructs a transformation matrix from 4 vectors (matrix columns). @@ -315,7 +315,7 @@ namespace Godot /// <param name="column1">The Y vector, or column index 1.</param> /// <param name="column2">The Z vector, or column index 2.</param> /// <param name="origin">The origin vector, or column index 3.</param> - public Transform(Vector3 column0, Vector3 column1, Vector3 column2, Vector3 origin) + public Transform3D(Vector3 column0, Vector3 column1, Vector3 column2, Vector3 origin) { basis = new Basis(column0, column1, column2); this.origin = origin; @@ -324,11 +324,11 @@ namespace Godot /// <summary> /// Constructs a transformation matrix from the given quaternion and origin vector. /// </summary> - /// <param name="quat">The <see cref="Godot.Quat"/> to create the basis from.</param> + /// <param name="quaternion">The <see cref="Godot.Quaternion"/> to create the basis from.</param> /// <param name="origin">The origin vector, or column index 3.</param> - public Transform(Quat quat, Vector3 origin) + public Transform3D(Quaternion quaternion, Vector3 origin) { - basis = new Basis(quat); + basis = new Basis(quaternion); this.origin = origin; } @@ -337,40 +337,40 @@ namespace Godot /// </summary> /// <param name="basis">The <see cref="Godot.Basis"/> to create the basis from.</param> /// <param name="origin">The origin vector, or column index 3.</param> - public Transform(Basis basis, Vector3 origin) + public Transform3D(Basis basis, Vector3 origin) { this.basis = basis; this.origin = origin; } - public static Transform operator *(Transform left, Transform right) + public static Transform3D operator *(Transform3D left, Transform3D right) { left.origin = left.Xform(right.origin); left.basis *= right.basis; return left; } - public static bool operator ==(Transform left, Transform right) + public static bool operator ==(Transform3D left, Transform3D right) { return left.Equals(right); } - public static bool operator !=(Transform left, Transform right) + public static bool operator !=(Transform3D left, Transform3D right) { return !left.Equals(right); } public override bool Equals(object obj) { - if (obj is Transform) + if (obj is Transform3D) { - return Equals((Transform)obj); + return Equals((Transform3D)obj); } return false; } - public bool Equals(Transform other) + public bool Equals(Transform3D other) { return basis.Equals(other.basis) && origin.Equals(other.origin); } @@ -381,7 +381,7 @@ namespace Godot /// </summary> /// <param name="other">The other transform to compare.</param> /// <returns>Whether or not the matrices are approximately equal.</returns> - public bool IsEqualApprox(Transform other) + public bool IsEqualApprox(Transform3D other) { return basis.IsEqualApprox(other.basis) && origin.IsEqualApprox(other.origin); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index ebfe70aa82..af053bd263 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -160,22 +160,20 @@ namespace Godot } /// <summary> - /// Returns the vector with a maximum length by limiting its length to `length`. + /// Returns a new vector with all components clamped between the + /// components of `min` and `max` using + /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>. /// </summary> - /// <param name="length">The length to limit to.</param> - /// <returns>The vector with its length limited.</returns> - public Vector2 Clamped(real_t length) + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector2 Clamp(Vector2 min, Vector2 max) { - var v = this; - real_t l = Length(); - - if (l > 0 && length < l) - { - v /= l; - v *= length; - } - - return v; + return new Vector2 + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y) + ); } /// <summary> @@ -335,6 +333,25 @@ namespace Godot } /// <summary> + /// Returns the vector with a maximum length by limiting its length to `length`. + /// </summary> + /// <param name="length">The length to limit to.</param> + /// <returns>The vector with its length limited.</returns> + public Vector2 LimitLength(real_t length = 1.0f) + { + Vector2 v = this; + real_t l = Length(); + + if (l > 0 && length < l) + { + v /= l; + v *= length; + } + + return v; + } + + /// <summary> /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. /// If both components are equal, this method returns <see cref="Axis.X"/>. /// </summary> @@ -425,7 +442,7 @@ namespace Godot #if DEBUG if (!normal.IsNormalized()) { - throw new ArgumentException("Argument is not normalized", nameof(normal)); + throw new ArgumentException("Argument is not normalized", nameof(normal)); } #endif return 2 * Dot(normal) * normal - this; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs index f605ba8fd0..9068593fd8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -120,6 +120,23 @@ namespace Godot } /// <summary> + /// Returns a new vector with all components clamped between the + /// components of `min` and `max` using + /// <see cref="Mathf.Clamp(int, int, int)"/>. + /// </summary> + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector2i Clamp(Vector2i min, Vector2i max) + { + return new Vector2i + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y) + ); + } + + /// <summary> /// Returns the cross product of this vector and `b`. /// </summary> /// <param name="b">The other vector.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 3b895bbbf6..31a9af2d9e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -140,6 +140,24 @@ namespace Godot } /// <summary> + /// Returns a new vector with all components clamped between the + /// components of `min` and `max` using + /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>. + /// </summary> + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector3 Clamp(Vector3 min, Vector3 max) + { + return new Vector3 + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y), + Mathf.Clamp(z, min.z, max.z) + ); + } + + /// <summary> /// Returns the cross product of this vector and `b`. /// </summary> /// <param name="b">The other vector.</param> @@ -313,6 +331,25 @@ namespace Godot } /// <summary> + /// Returns the vector with a maximum length by limiting its length to `length`. + /// </summary> + /// <param name="length">The length to limit to.</param> + /// <returns>The vector with its length limited.</returns> + public Vector3 LimitLength(real_t length = 1.0f) + { + Vector3 v = this; + real_t l = Length(); + + if (l > 0 && length < l) + { + v /= l; + v *= length; + } + + return v; + } + + /// <summary> /// Returns the axis of the vector's largest value. See <see cref="Axis"/>. /// If all components are equal, this method returns <see cref="Axis.X"/>. /// </summary> @@ -419,7 +456,7 @@ namespace Godot #if DEBUG if (!normal.IsNormalized()) { - throw new ArgumentException("Argument is not normalized", nameof(normal)); + throw new ArgumentException("Argument is not normalized", nameof(normal)); } #endif return 2.0f * Dot(normal) * normal - this; @@ -437,7 +474,7 @@ namespace Godot #if DEBUG if (!axis.IsNormalized()) { - throw new ArgumentException("Argument is not normalized", nameof(axis)); + throw new ArgumentException("Argument is not normalized", nameof(axis)); } #endif return new Basis(axis, phi).Xform(this); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs index bf25ba9cb3..e727afa3ff 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -89,6 +89,24 @@ namespace Godot } /// <summary> + /// Returns a new vector with all components clamped between the + /// components of `min` and `max` using + /// <see cref="Mathf.Clamp(int, int, int)"/>. + /// </summary> + /// <param name="min">The vector with minimum allowed values.</param> + /// <param name="max">The vector with maximum allowed values.</param> + /// <returns>The vector with all components clamped.</returns> + public Vector3i Clamp(Vector3i min, Vector3i max) + { + return new Vector3i + ( + Mathf.Clamp(x, min.x, max.x), + Mathf.Clamp(y, min.y, max.y), + Mathf.Clamp(z, min.z, max.z) + ); + } + + /// <summary> /// Returns the squared distance between this vector and `b`. /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if /// you need to compare vectors or need the squared distance for some formula. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 54aaaf1f92..1fcfe74c86 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -50,7 +50,7 @@ <Compile Include="Core\NodePath.cs" /> <Compile Include="Core\Object.base.cs" /> <Compile Include="Core\Plane.cs" /> - <Compile Include="Core\Quat.cs" /> + <Compile Include="Core\Quaternion.cs" /> <Compile Include="Core\Rect2.cs" /> <Compile Include="Core\Rect2i.cs" /> <Compile Include="Core\RID.cs" /> @@ -58,8 +58,8 @@ <Compile Include="Core\SignalAwaiter.cs" /> <Compile Include="Core\StringExtensions.cs" /> <Compile Include="Core\StringName.cs" /> - <Compile Include="Core\Transform.cs" /> <Compile Include="Core\Transform2D.cs" /> + <Compile Include="Core\Transform3D.cs" /> <Compile Include="Core\UnhandledExceptionArgs.cs" /> <Compile Include="Core\Vector2.cs" /> <Compile Include="Core\Vector2i.cs" /> diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index d66cc29b9a..341ca88728 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -109,8 +109,8 @@ void CachedData::clear_godot_api_cache() { class_Vector3 = nullptr; class_Vector3i = nullptr; class_Basis = nullptr; - class_Quat = nullptr; - class_Transform = nullptr; + class_Quaternion = nullptr; + class_Transform3D = nullptr; class_AABB = nullptr; class_Color = nullptr; class_Plane = nullptr; @@ -238,8 +238,8 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3)); CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i)); CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); - CACHE_CLASS_AND_CHECK(Quat, GODOT_API_CLASS(Quat)); - CACHE_CLASS_AND_CHECK(Transform, GODOT_API_CLASS(Transform)); + CACHE_CLASS_AND_CHECK(Quaternion, GODOT_API_CLASS(Quaternion)); + CACHE_CLASS_AND_CHECK(Transform3D, GODOT_API_CLASS(Transform3D)); CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB)); CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color)); CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 51370da452..3d867060f5 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -80,8 +80,8 @@ struct CachedData { GDMonoClass *class_Vector3; GDMonoClass *class_Vector3i; GDMonoClass *class_Basis; - GDMonoClass *class_Quat; - GDMonoClass *class_Transform; + GDMonoClass *class_Quaternion; + GDMonoClass *class_Transform3D; GDMonoClass *class_AABB; GDMonoClass *class_Color; GDMonoClass *class_Plane; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 1d4d52dfce..111eaa0bbf 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -146,14 +146,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } - if (tclass == CACHED_CLASS(Quat)) { - GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat()); + if (tclass == CACHED_CLASS(Quaternion)) { + GDMonoMarshal::M_Quaternion from = MARSHALLED_OUT(Quaternion, p_value.operator ::Quaternion()); mono_field_set_value(p_object, mono_field, &from); break; } - if (tclass == CACHED_CLASS(Transform)) { - GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform()); + if (tclass == CACHED_CLASS(Transform3D)) { + GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_value.operator ::Transform3D()); mono_field_set_value(p_object, mono_field, &from); break; } @@ -336,8 +336,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_value.operator ::Plane()); mono_field_set_value(p_object, mono_field, &from); } break; - case Variant::QUAT: { - GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat()); + case Variant::QUATERNION: { + GDMonoMarshal::M_Quaternion from = MARSHALLED_OUT(Quaternion, p_value.operator ::Quaternion()); mono_field_set_value(p_object, mono_field, &from); } break; case Variant::AABB: { @@ -348,8 +348,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis()); mono_field_set_value(p_object, mono_field, &from); } break; - case Variant::TRANSFORM: { - GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform()); + case Variant::TRANSFORM3D: { + GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_value.operator ::Transform3D()); mono_field_set_value(p_object, mono_field, &from); } break; case Variant::COLOR: { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 359f6bba4d..c8f80e7777 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -104,12 +104,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ return Variant::BASIS; } - if (vtclass == CACHED_CLASS(Quat)) { - return Variant::QUAT; + if (vtclass == CACHED_CLASS(Quaternion)) { + return Variant::QUATERNION; } - if (vtclass == CACHED_CLASS(Transform)) { - return Variant::TRANSFORM; + if (vtclass == CACHED_CLASS(Transform3D)) { + return Variant::TRANSFORM3D; } if (vtclass == CACHED_CLASS(AABB)) { @@ -508,9 +508,9 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var.operator ::Plane()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from); } - case Variant::QUAT: { - GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var.operator ::Quat()); - return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from); + case Variant::QUATERNION: { + GDMonoMarshal::M_Quaternion from = MARSHALLED_OUT(Quaternion, p_var.operator ::Quaternion()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quaternion), &from); } case Variant::AABB: { GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var.operator ::AABB()); @@ -520,9 +520,9 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var.operator ::Basis()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from); } - case Variant::TRANSFORM: { - GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var.operator ::Transform()); - return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from); + case Variant::TRANSFORM3D: { + GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_var.operator ::Transform3D()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform3D), &from); } case Variant::COLOR: { GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var.operator ::Color()); @@ -619,8 +619,8 @@ size_t variant_get_managed_unboxed_size(const ManagedType &p_type) { RETURN_CHECK_FOR_STRUCT(Vector3); RETURN_CHECK_FOR_STRUCT(Vector3i); RETURN_CHECK_FOR_STRUCT(Basis); - RETURN_CHECK_FOR_STRUCT(Quat); - RETURN_CHECK_FOR_STRUCT(Transform); + RETURN_CHECK_FOR_STRUCT(Quaternion); + RETURN_CHECK_FOR_STRUCT(Transform3D); RETURN_CHECK_FOR_STRUCT(AABB); RETURN_CHECK_FOR_STRUCT(Color); RETURN_CHECK_FOR_STRUCT(Plane); @@ -724,8 +724,8 @@ void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type RETURN_CHECK_FOR_STRUCT(Vector3); RETURN_CHECK_FOR_STRUCT(Vector3i); RETURN_CHECK_FOR_STRUCT(Basis); - RETURN_CHECK_FOR_STRUCT(Quat); - RETURN_CHECK_FOR_STRUCT(Transform); + RETURN_CHECK_FOR_STRUCT(Quaternion); + RETURN_CHECK_FOR_STRUCT(Transform3D); RETURN_CHECK_FOR_STRUCT(AABB); RETURN_CHECK_FOR_STRUCT(Color); RETURN_CHECK_FOR_STRUCT(Plane); @@ -880,8 +880,8 @@ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_ty RETURN_CHECK_FOR_STRUCT(Vector3); RETURN_CHECK_FOR_STRUCT(Vector3i); RETURN_CHECK_FOR_STRUCT(Basis); - RETURN_CHECK_FOR_STRUCT(Quat); - RETURN_CHECK_FOR_STRUCT(Transform); + RETURN_CHECK_FOR_STRUCT(Quaternion); + RETURN_CHECK_FOR_STRUCT(Transform3D); RETURN_CHECK_FOR_STRUCT(AABB); RETURN_CHECK_FOR_STRUCT(Color); RETURN_CHECK_FOR_STRUCT(Plane); @@ -1036,12 +1036,12 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); } - if (vtclass == CACHED_CLASS(Quat)) { - return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj)); + if (vtclass == CACHED_CLASS(Quaternion)) { + return MARSHALLED_IN(Quaternion, unbox_addr<GDMonoMarshal::M_Quaternion>(p_obj)); } - if (vtclass == CACHED_CLASS(Transform)) { - return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj)); + if (vtclass == CACHED_CLASS(Transform3D)) { + return MARSHALLED_IN(Transform3D, unbox_addr<GDMonoMarshal::M_Transform3D>(p_obj)); } if (vtclass == CACHED_CLASS(AABB)) { diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 668809ae5d..88afc7ebc5 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -263,15 +263,15 @@ enum { MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array - MATCHES_Quat = (MATCHES_real_t && (sizeof(Quat) == (sizeof(real_t) * 4)) && - offsetof(Quat, x) == (sizeof(real_t) * 0) && - offsetof(Quat, y) == (sizeof(real_t) * 1) && - offsetof(Quat, z) == (sizeof(real_t) * 2) && - offsetof(Quat, w) == (sizeof(real_t) * 3)), + MATCHES_Quaternion = (MATCHES_real_t && (sizeof(Quaternion) == (sizeof(real_t) * 4)) && + offsetof(Quaternion, x) == (sizeof(real_t) * 0) && + offsetof(Quaternion, y) == (sizeof(real_t) * 1) && + offsetof(Quaternion, z) == (sizeof(real_t) * 2) && + offsetof(Quaternion, w) == (sizeof(real_t) * 3)), - MATCHES_Transform = (MATCHES_Basis && MATCHES_Vector3 && (sizeof(Transform) == (sizeof(Basis) + sizeof(Vector3))) && - offsetof(Transform, basis) == 0 && - offsetof(Transform, origin) == sizeof(Basis)), + MATCHES_Transform3D = (MATCHES_Basis && MATCHES_Vector3 && (sizeof(Transform3D) == (sizeof(Basis) + sizeof(Vector3))) && + offsetof(Transform3D, basis) == 0 && + offsetof(Transform3D, origin) == sizeof(Basis)), MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && offsetof(AABB, position) == (sizeof(Vector3) * 0) && @@ -292,7 +292,7 @@ enum { #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY /* clang-format off */ static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && - MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color && + MATCHES_Basis && MATCHES_Quaternion && MATCHES_Transform3D && MATCHES_AABB && MATCHES_Color && MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); /* clang-format on */ #endif @@ -420,29 +420,29 @@ struct M_Basis { } }; -struct M_Quat { +struct M_Quaternion { real_t x, y, z, w; - static _FORCE_INLINE_ Quat convert_to(const M_Quat &p_from) { - return Quat(p_from.x, p_from.y, p_from.z, p_from.w); + static _FORCE_INLINE_ Quaternion convert_to(const M_Quaternion &p_from) { + return Quaternion(p_from.x, p_from.y, p_from.z, p_from.w); } - static _FORCE_INLINE_ M_Quat convert_from(const Quat &p_from) { - M_Quat ret = { p_from.x, p_from.y, p_from.z, p_from.w }; + static _FORCE_INLINE_ M_Quaternion convert_from(const Quaternion &p_from) { + M_Quaternion ret = { p_from.x, p_from.y, p_from.z, p_from.w }; return ret; } }; -struct M_Transform { +struct M_Transform3D { M_Basis basis; M_Vector3 origin; - static _FORCE_INLINE_ Transform convert_to(const M_Transform &p_from) { - return Transform(M_Basis::convert_to(p_from.basis), M_Vector3::convert_to(p_from.origin)); + static _FORCE_INLINE_ Transform3D convert_to(const M_Transform3D &p_from) { + return Transform3D(M_Basis::convert_to(p_from.basis), M_Vector3::convert_to(p_from.origin)); } - static _FORCE_INLINE_ M_Transform convert_from(const Transform &p_from) { - M_Transform ret = { M_Basis::convert_from(p_from.basis), M_Vector3::convert_from(p_from.origin) }; + static _FORCE_INLINE_ M_Transform3D convert_from(const Transform3D &p_from) { + M_Transform3D ret = { M_Basis::convert_from(p_from.basis), M_Vector3::convert_from(p_from.origin) }; return ret; } }; @@ -533,8 +533,8 @@ DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) DECL_TYPE_MARSHAL_TEMPLATES(Vector3) DECL_TYPE_MARSHAL_TEMPLATES(Vector3i) DECL_TYPE_MARSHAL_TEMPLATES(Basis) -DECL_TYPE_MARSHAL_TEMPLATES(Quat) -DECL_TYPE_MARSHAL_TEMPLATES(Transform) +DECL_TYPE_MARSHAL_TEMPLATES(Quaternion) +DECL_TYPE_MARSHAL_TEMPLATES(Transform3D) DECL_TYPE_MARSHAL_TEMPLATES(AABB) DECL_TYPE_MARSHAL_TEMPLATES(Color) DECL_TYPE_MARSHAL_TEMPLATES(Plane) diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 66558efa8c..88c0145ebc 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -64,7 +64,7 @@ void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { camera_ray_masks.resize(ray_packets_count * TILE_SIZE * TILE_SIZE); } -void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { +void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { CameraRayThreadData td; td.camera_matrix = p_cam_projection; td.camera_transform = p_cam_transform; @@ -82,7 +82,7 @@ void RaycastOcclusionCull::RaycastHZBuffer::_camera_rays_threaded(uint32_t p_thr _generate_camera_rays(p_data->camera_transform, p_data->camera_matrix, p_data->camera_orthogonal, from, to); } -void RaycastOcclusionCull::RaycastHZBuffer::_generate_camera_rays(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, int p_from, int p_to) { +void RaycastOcclusionCull::RaycastHZBuffer::_generate_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, int p_from, int p_to) { Size2i buffer_size = sizes[0]; CameraMatrix inv_camera_matrix = p_cam_projection.inverse(); @@ -227,7 +227,7 @@ void RaycastOcclusionCull::remove_scenario(RID p_scenario) { scenario.removed = true; } -void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform &p_xform, bool p_enabled) { +void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { ERR_FAIL_COND(!scenarios.has(p_scenario)); Scenario &scenario = scenarios[p_scenario]; @@ -345,7 +345,7 @@ void RaycastOcclusionCull::Scenario::_transform_vertices_thread(uint32_t p_threa _transform_vertices_range(p_data->read, p_data->write, p_data->xform, from, to); } -void RaycastOcclusionCull::Scenario::_transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform &p_xform, int p_from, int p_to) { +void RaycastOcclusionCull::Scenario::_transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to) { for (int i = p_from; i < p_to; i++) { p_write[i] = p_xform.xform(p_read[i]); } @@ -491,7 +491,7 @@ void RaycastOcclusionCull::buffer_set_size(RID p_buffer, const Vector2i &p_size) buffers[p_buffer].resize(p_size); } -void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { +void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { if (!buffers.has(p_buffer)) { return; } diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index acaceb9459..d9ca57cf24 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -52,14 +52,14 @@ public: struct CameraRayThreadData { CameraMatrix camera_matrix; - Transform camera_transform; + Transform3D camera_transform; bool camera_orthogonal; int thread_count; Size2i buffer_size; }; void _camera_rays_threaded(uint32_t p_thread, CameraRayThreadData *p_data); - void _generate_camera_rays(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, int p_from, int p_to); + void _generate_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, int p_from, int p_to); public: LocalVector<RayPacket> camera_rays; @@ -69,7 +69,7 @@ public: virtual void clear() override; virtual void resize(const Size2i &p_size) override; void sort_rays(); - void update_camera_rays(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); + void update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); }; private: @@ -99,7 +99,7 @@ private: RID occluder; LocalVector<uint32_t> indices; LocalVector<Vector3> xformed_vertices; - Transform xform; + Transform3D xform; bool enabled = true; bool removed = false; }; @@ -113,7 +113,7 @@ private: struct TransformThreadData { uint32_t thread_count; uint32_t vertex_count; - Transform xform; + Transform3D xform; const Vector3 *read; Vector3 *write; }; @@ -134,7 +134,7 @@ private: void _update_dirty_instance_thread(int p_idx, RID *p_instances); void _update_dirty_instance(int p_idx, RID *p_instances, ThreadWorkPool *p_thread_pool); void _transform_vertices_thread(uint32_t p_thread, TransformThreadData *p_data); - void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform &p_xform, int p_from, int p_to); + void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to); static void _commit_scene(void *p_ud); bool update(ThreadWorkPool &p_thread_pool); @@ -164,7 +164,7 @@ public: virtual void add_scenario(RID p_scenario) override; virtual void remove_scenario(RID p_scenario) override; - virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform &p_xform, bool p_enabled) override; + virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) override; virtual void scenario_remove_instance(RID p_scenario, RID p_instance) override; virtual void add_buffer(RID p_buffer) override; @@ -172,7 +172,7 @@ public: virtual HZBuffer *buffer_get_ptr(RID p_buffer) override; virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) override; virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) override; - virtual void buffer_update(RID p_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; virtual RID buffer_get_debug_texture(RID p_buffer) override; virtual void set_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality) override; diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 7b421bdc16..4400445f30 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -302,7 +302,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { } } - /* and now we have it all. initialize decoders */ + /* And now we have it all. Initialize decoders. */ if (theora_p) { td = th_decode_alloc(&ti, ts); px_fmt = ti.pixel_fmt; @@ -484,10 +484,10 @@ void VideoStreamPlaybackTheora::update(float p_delta) { //printf("frame time %f, play time %f, ready %i\n", (float)videobuf_time, get_time(), videobuf_ready); - /* is it already too old to be useful? This is only actually - useful cosmetically after a SIGSTOP. Note that we have to + /* is it already too old to be useful? This is only actually + useful cosmetically after a SIGSTOP. Note that we have to decode the frame even if we don't show it (for now) due to - keyframing. Soon enough libtheora will be able to deal + keyframing. Soon enough libtheora will be able to deal with non-keyframe seeks. */ if (videobuf_time >= get_time()) { diff --git a/modules/vhacd/config.py b/modules/vhacd/config.py index d22f9454ed..a42f27fbe1 100644 --- a/modules/vhacd/config.py +++ b/modules/vhacd/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index 5112ea43a7..0798375a96 100644 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -4,7 +4,7 @@ A script implemented in the Visual Script programming environment. </brief_description> <description> - A script implemented in the Visual Script programming environment. The script extends the functionality of all objects that instance it. + A script implemented in the Visual Script programming environment. The script extends the functionality of all objects that instance it. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. You are most likely to use this class via the Visual Script editor or when writing plugins for it. </description> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index b863f622bd..c9ed912ac1 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -954,60 +954,10 @@ bool VisualScript::are_subnodes_edited() const { } #endif -Vector<ScriptNetData> VisualScript::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> VisualScript::get_rpc_methods() const { return rpc_functions; } -uint16_t VisualScript::get_rpc_method_id(const StringName &p_method) const { - for (int i = 0; i < rpc_functions.size(); i++) { - if (rpc_functions[i].name == p_method) { - return i; - } - } - return UINT16_MAX; -} - -StringName VisualScript::get_rpc_method(const uint16_t p_rpc_method_id) const { - ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName()); - return rpc_functions[p_rpc_method_id].name; -} - -MultiplayerAPI::RPCMode VisualScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_functions[p_rpc_method_id].mode; -} - -MultiplayerAPI::RPCMode VisualScript::get_rpc_mode(const StringName &p_method) const { - return get_rpc_mode_by_id(get_rpc_method_id(p_method)); -} - -Vector<ScriptNetData> VisualScript::get_rset_properties() const { - return rpc_variables; -} - -uint16_t VisualScript::get_rset_property_id(const StringName &p_variable) const { - for (int i = 0; i < rpc_variables.size(); i++) { - if (rpc_variables[i].name == p_variable) { - return i; - } - } - return UINT16_MAX; -} - -StringName VisualScript::get_rset_property(const uint16_t p_rset_property_id) const { - ERR_FAIL_COND_V(p_rset_property_id >= rpc_variables.size(), StringName()); - return rpc_variables[p_rset_property_id].name; -} - -MultiplayerAPI::RPCMode VisualScript::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const { - ERR_FAIL_COND_V(p_rset_variable_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED); - return rpc_variables[p_rset_variable_id].mode; -} - -MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable) const { - return get_rset_mode_by_id(get_rset_property_id(p_variable)); -} - void VisualScript::_set_data(const Dictionary &p_data) { Dictionary d = p_data; if (d.has("base_type")) { @@ -1065,7 +1015,6 @@ void VisualScript::_set_data(const Dictionary &p_data) { // Takes all the rpc methods. rpc_functions.clear(); - rpc_variables.clear(); List<StringName> fns; functions.get_key_list(&fns); for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) { @@ -1073,9 +1022,10 @@ void VisualScript::_set_data(const Dictionary &p_data) { Ref<VisualScriptFunction> vsf = nodes[functions[E->get()].func_id].node; if (vsf.is_valid()) { if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { - ScriptNetData nd; + MultiplayerAPI::RPCConfig nd; nd.name = E->get(); - nd.mode = vsf->get_rpc_mode(); + nd.rpc_mode = vsf->get_rpc_mode(); + nd.transfer_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO if (rpc_functions.find(nd) == -1) { rpc_functions.push_back(nd); } @@ -1085,7 +1035,7 @@ void VisualScript::_set_data(const Dictionary &p_data) { } // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<SortNetData>(); + rpc_functions.sort_custom<MultiplayerAPI::SortRPCConfig>(); } Dictionary VisualScript::_get_data() const { @@ -1882,46 +1832,10 @@ Ref<Script> VisualScriptInstance::get_script() const { return script; } -Vector<ScriptNetData> VisualScriptInstance::get_rpc_methods() const { +const Vector<MultiplayerAPI::RPCConfig> VisualScriptInstance::get_rpc_methods() const { return script->get_rpc_methods(); } -uint16_t VisualScriptInstance::get_rpc_method_id(const StringName &p_method) const { - return script->get_rpc_method_id(p_method); -} - -StringName VisualScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { - return script->get_rpc_method(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - return script->get_rpc_mode_by_id(p_rpc_method_id); -} - -MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const { - return script->get_rpc_mode(p_method); -} - -Vector<ScriptNetData> VisualScriptInstance::get_rset_properties() const { - return script->get_rset_properties(); -} - -uint16_t VisualScriptInstance::get_rset_property_id(const StringName &p_variable) const { - return script->get_rset_property_id(p_variable); -} - -StringName VisualScriptInstance::get_rset_property(const uint16_t p_rset_property_id) const { - return script->get_rset_property(p_rset_property_id); -} - -MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const { - return script->get_rset_mode_by_id(p_rset_variable_id); -} - -MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const { - return script->get_rset_mode(p_variable); -} - void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { script = p_script; owner = p_owner; diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index cc78b3242d..3c4a26a2a3 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -234,8 +234,7 @@ private: HashMap<StringName, Function> functions; HashMap<StringName, Variable> variables; Map<StringName, Vector<Argument>> custom_signals; - Vector<ScriptNetData> rpc_functions; - Vector<ScriptNetData> rpc_variables; + Vector<MultiplayerAPI::RPCConfig> rpc_functions; Map<Object *, VisualScriptInstance *> instances; @@ -363,17 +362,7 @@ public: virtual int get_member_line(const StringName &p_member) const override; - virtual Vector<ScriptNetData> get_rpc_methods() const override; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const override; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - - virtual Vector<ScriptNetData> get_rset_properties() const override; - virtual uint16_t get_rset_property_id(const StringName &p_property) const override; - virtual StringName get_rset_property(const uint16_t p_rset_property_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const override; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override; #ifdef TOOLS_ENABLED virtual bool are_subnodes_edited() const; @@ -454,17 +443,7 @@ public: virtual ScriptLanguage *get_language(); - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_property) const; - virtual StringName get_rset_property(const uint16_t p_rset_property_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const; VisualScriptInstance(); ~VisualScriptInstance(); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 7432440603..5cfc228fae 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -381,7 +381,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; - case Variant::QUAT: + case Variant::QUATERNION: color = Color(0.93, 0.41, 0.64); break; case Variant::AABB: @@ -390,7 +390,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::BASIS: color = Color(0.89, 0.93, 0.41); break; - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: color = Color(0.96, 0.66, 0.43); break; @@ -487,7 +487,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; - case Variant::QUAT: + case Variant::QUATERNION: color = Color(0.93, 0.41, 0.64); break; case Variant::AABB: @@ -496,7 +496,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::BASIS: color = Color(0.7, 0.73, 0.1); break; - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: color = Color(0.96, 0.56, 0.28); break; @@ -624,7 +624,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Control::get_theme_icon("Vector3i", "EditorIcons"), Control::get_theme_icon("Transform2D", "EditorIcons"), Control::get_theme_icon("Plane", "EditorIcons"), - Control::get_theme_icon("Quat", "EditorIcons"), + Control::get_theme_icon("Quaternion", "EditorIcons"), Control::get_theme_icon("AABB", "EditorIcons"), Control::get_theme_icon("Basis", "EditorIcons"), Control::get_theme_icon("Transform", "EditorIcons"), @@ -739,6 +739,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { } Color c = sbf->get_border_color(); + c = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85); Color ic = c; gnode->add_theme_color_override("title_color", c); c.a = 1; @@ -1074,7 +1075,7 @@ void VisualScriptEditor::_update_members() { Control::get_theme_icon("Vector3i", "EditorIcons"), Control::get_theme_icon("Transform2D", "EditorIcons"), Control::get_theme_icon("Plane", "EditorIcons"), - Control::get_theme_icon("Quat", "EditorIcons"), + Control::get_theme_icon("Quaternion", "EditorIcons"), Control::get_theme_icon("AABB", "EditorIcons"), Control::get_theme_icon("Basis", "EditorIcons"), Control::get_theme_icon("Transform", "EditorIcons"), @@ -1852,7 +1853,7 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { } member_name = ti->get_text(0); } - if (ED_IS_SHORTCUT("visual_script_editor/delete_selected", p_event)) { + if (ED_IS_SHORTCUT("ui_graph_delete", p_event)) { _member_option(MEMBER_REMOVE); } if (ED_IS_SHORTCUT("visual_script_editor/edit_member", p_event)) { @@ -4120,7 +4121,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("visual_script_editor/delete_selected"), MEMBER_REMOVE); + member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); member_popup->popup(); return; } @@ -4130,7 +4131,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("visual_script_editor/delete_selected"), MEMBER_REMOVE); + member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); member_popup->popup(); return; } @@ -4140,7 +4141,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("visual_script_editor/delete_selected"), MEMBER_REMOVE); + member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); member_popup->popup(); return; } diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 9310b86627..a0ba7b1962 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -737,20 +737,22 @@ public: } int to_id = 0; - bool reliable = true; + //bool reliable = true; if (rpc_mode >= VisualScriptFunctionCall::RPC_RELIABLE_TO_ID) { to_id = *p_args[0]; p_args += 1; p_argcount -= 1; - if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE_TO_ID) { - reliable = false; - } - } else if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE) { - reliable = false; + //if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE_TO_ID) { + //reliable = false; + //} } + //else if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE) { + //reliable = false; + //} - node->rpcp(to_id, !reliable, function, p_args, p_argcount); + // TODO reliable? + node->rpcp(to_id, function, p_args, p_argcount); return true; } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index fed6637acb..07dc3dfaf6 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -3918,10 +3918,10 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUAT), create_node_deconst_typed<Variant::Type::QUAT>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUATERNION), create_node_deconst_typed<Variant::Type::QUATERNION>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM), create_node_deconst_typed<Variant::Type::TRANSFORM>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM3D), create_node_deconst_typed<Variant::Type::TRANSFORM3D>); VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>); for (int i = 1; i < Variant::VARIANT_MAX; i++) { diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 93e14f60d0..7a3cd5c0d1 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -108,7 +108,7 @@ void VisualScriptPropertySelector::_update_search() { vbc->get_theme_icon("Vector3", "EditorIcons"), vbc->get_theme_icon("Transform2D", "EditorIcons"), vbc->get_theme_icon("Plane", "EditorIcons"), - vbc->get_theme_icon("Quat", "EditorIcons"), + vbc->get_theme_icon("Quaternion", "EditorIcons"), vbc->get_theme_icon("AABB", "EditorIcons"), vbc->get_theme_icon("Basis", "EditorIcons"), vbc->get_theme_icon("Transform", "EditorIcons"), diff --git a/modules/webxr/config.py b/modules/webxr/config.py index 9efebed4e6..f676ef3483 100644 --- a/modules/webxr/config.py +++ b/modules/webxr/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 06f3fe6284..a628cb0549 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -266,7 +266,7 @@ void WebXRInterfaceJS::uninitialize() { }; Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) { - Transform transform; + Transform3D transform; transform.basis.elements[0].x = p_js_matrix[0]; transform.basis.elements[1].x = p_js_matrix[1]; @@ -305,8 +305,8 @@ Size2 WebXRInterfaceJS::get_render_targetsize() { return render_targetsize; }; -Transform WebXRInterfaceJS::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { - Transform transform_for_eye; +Transform WebXRInterfaceJS::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) { + Transform3D transform_for_eye; XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, transform_for_eye); @@ -399,7 +399,7 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) { float *tracker_matrix = godot_webxr_get_controller_transform(p_controller_id); if (tracker_matrix) { - Transform transform = _js_matrix_to_transform(tracker_matrix); + Transform3D transform = _js_matrix_to_transform(tracker_matrix); tracker->set_position(transform.origin); tracker->set_orientation(transform.basis); free(tracker_matrix); diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 7c841c1911..e9274a06e4 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -56,7 +56,7 @@ private: bool controllers_state[2]; Size2 render_targetsize; - Transform _js_matrix_to_transform(float *p_js_matrix); + Transform3D _js_matrix_to_transform(float *p_js_matrix); void _update_tracker(int p_controller_id); public: @@ -84,7 +84,7 @@ public: virtual Size2 get_render_targetsize() override; virtual bool is_stereo() override; - virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) override; + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) override; virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) override; virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye) override; virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) override; diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 1379baf154..a2f47dcccb 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -81,7 +81,7 @@ private: 1004, //CURSOR_BUSY 1021, //CURSOR_DRAG 1021, //CURSOR_CAN_DRO - 1000, //CURSOR_FORBIDD (no corresponding icon in Android's icon so fallback to default) + 1000, //CURSOR_FORBIDD (no corresponding icon in Android's icon so fallback to default) 1015, //CURSOR_VSIZE 1014, //CURSOR_HSIZE 1017, //CURSOR_BDIAGSI diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index a7fe500be2..a28888d80d 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -118,8 +118,8 @@ task zipCustomBuild(type: Zip) { } from(fileTree(dir: 'app', excludes: ['**/build/**', '**/.gradle/**', '**/*.iml']), fileTree(dir: '.', includes: ['gradle.properties', 'gradlew', 'gradlew.bat', 'gradle/**'])) include '**/*' - archiveName 'android_source.zip' - destinationDir(file(binDir)) + archiveFileName = 'android_source.zip' + destinationDirectory = file(binDir) } def templateExcludedBuildTask() { diff --git a/platform/android/java/gradlew.bat b/platform/android/java/gradlew.bat index f9553162f1..11cc30edb0 100644 --- a/platform/android/java/gradlew.bat +++ b/platform/android/java/gradlew.bat @@ -1,7 +1,7 @@ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem Gradle startup script for Windows @rem @rem ########################################################################## @@ -75,7 +75,7 @@ if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd diff --git a/platform/android/java/lib/res/values/strings.xml b/platform/android/java/lib/res/values/strings.xml index 590b066d8a..010006b81e 100644 --- a/platform/android/java/lib/res/values/strings.xml +++ b/platform/android/java/lib/res/values/strings.xml @@ -6,7 +6,7 @@ <string name="text_button_resume_cellular">Resume download</string> <string name="text_button_wifi_settings">Wi-Fi settings</string> <string name="text_verifying_download">Verifying Download</string> - <string name="text_validation_complete">XAPK File Validation Complete. Select OK to exit.</string> + <string name="text_validation_complete">XAPK File Validation Complete. Select OK to exit.</string> <string name="text_validation_failed">XAPK File Validation Failed.</string> <string name="text_button_pause">Pause Download</string> <string name="text_button_resume">Resume Download</string> diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt index f0e37d80b8..b01dc2653a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt @@ -115,7 +115,7 @@ open internal class VkSurfaceView(context: Context) : SurfaceView(context), Surf /** * Tear down the rendering thread. * - * Must not be called before a [VkRenderer] has been set. + * Must not be called before a [VkRenderer] has been set. */ fun onDestroy() { vkThread.blockingExit() diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h index 173ac115a2..c5c1c690a2 100644 --- a/platform/android/plugin/godot_plugin_config.h +++ b/platform/android/plugin/godot_plugin_config.h @@ -37,8 +37,8 @@ /* The `config` section and fields are required and defined as follow: -- **name**: name of the plugin -- **binary_type**: can be either `local` or `remote`. The type affects the **binary** field +- **name**: name of the plugin. +- **binary_type**: can be either `local` or `remote`. The type affects the **binary** field. - **binary**: - if **binary_type** is `local`, then this should be the filename of the plugin `aar` file in the `res://android/plugins` directory (e.g: `MyPlugin.aar`). - if **binary_type** is `remote`, then this should be a declaration for a remote gradle binary (e.g: "org.godot.example:my-plugin:0.0.0"). diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index cce1f8dca7..1cc05a2e19 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -407,9 +407,10 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso // Mouse mode void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) { - ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform."); - if (p_mode == mouse_get_mode()) + ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform."); + if (p_mode == mouse_get_mode()) { return; + } if (p_mode == MOUSE_MODE_VISIBLE) { godot_js_display_cursor_set_visible(1); diff --git a/platform/javascript/js/libs/library_godot_fetch.js b/platform/javascript/js/libs/library_godot_fetch.js index de5ae2b1ae..04b90aea9c 100644 --- a/platform/javascript/js/libs/library_godot_fetch.js +++ b/platform/javascript/js/libs/library_godot_fetch.js @@ -29,7 +29,7 @@ /*************************************************************************/ const GodotFetch = { - $GodotFetch__deps: ['$GodotRuntime'], + $GodotFetch__deps: ['$IDHandler', '$GodotRuntime'], $GodotFetch: { onread: function (id, result) { diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index b50b5f3479..8b6922699c 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -360,7 +360,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { return; } - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { XUngrabPointer(x11_display, CurrentTime); } @@ -376,7 +376,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { } mouse_mode = p_mode; - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { //flush pending motion events _flush_mouse_motion(); WindowData &main_window = windows[MAIN_WINDOW_ID]; @@ -2766,7 +2766,7 @@ void DisplayServerX11::process_events() { do_mouse_warp = false; // Is the current mouse mode one where it needs to be grabbed. - bool mouse_mode_grab = mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED; + bool mouse_mode_grab = mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN; xi.pressure = 0; xi.tilt = Vector2(); @@ -3030,7 +3030,7 @@ void DisplayServerX11::process_events() { for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { if (mouse_mode == MOUSE_MODE_CONFINED) { XUndefineCursor(x11_display, E->get().x11_window); - } else if (mouse_mode == MOUSE_MODE_CAPTURED) { // or re-hide it in captured mode + } else if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { // Or re-hide it. XDefineCursor(x11_display, E->get().x11_window, null_cursor); } diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index f53b60891f..408feb4db9 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -884,7 +884,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i return; } - if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) { + if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED || DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED_HIDDEN) { // Discard late events if (([event timestamp]) < DS_OSX->last_warp) { return; @@ -2106,7 +2106,12 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { } else if (p_mode == MOUSE_MODE_CONFINED) { CGDisplayShowCursor(kCGDirectMainDisplay); CGAssociateMouseAndMouseCursorPosition(false); - } else { + } else if (p_mode == MOUSE_MODE_CONFINED_HIDDEN) { + if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + CGDisplayHideCursor(kCGDirectMainDisplay); + } + CGAssociateMouseAndMouseCursorPosition(false); + } else { // MOUSE_MODE_VISIBLE CGDisplayShowCursor(kCGDirectMainDisplay); CGAssociateMouseAndMouseCursorPosition(true); } @@ -2143,7 +2148,7 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) { CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); CGAssociateMouseAndMouseCursorPosition(false); CGWarpMouseCursorPosition(lMouseWarpPos); - if (mouse_mode != MOUSE_MODE_CONFINED) { + if (mouse_mode != MOUSE_MODE_CONFINED && mouse_mode != MOUSE_MODE_CONFINED_HIDDEN) { CGAssociateMouseAndMouseCursorPosition(true); } } diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 9d6ff10483..bac8620086 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -333,8 +333,9 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co os->input_event(screen_drag); } else { // In case the mouse grabbed, MouseMoved will handle this - if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) + if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) { return; + } Ref<InputEventMouseMotion> mouse_motion; mouse_motion.instance(); @@ -351,8 +352,9 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) { // In case the mouse isn't grabbed, PointerMoved will handle this - if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED) + if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED) { return; + } Windows::Foundation::Point pos; pos.X = last_mouse_pos.X + args->MouseDelta.X; diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 435f829c9b..65934b6681 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -400,14 +400,12 @@ void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, Gyrom void OS_UWP::set_mouse_mode(MouseMode p_mode) { if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) { CoreWindow::GetForCurrentThread()->SetPointerCapture(); - } else { CoreWindow::GetForCurrentThread()->ReleasePointerCapture(); } - if (p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_HIDDEN) { + if (p_mode == MouseMode::MOUSE_MODE_HIDDEN || p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_CONFINED_HIDDEN) { CoreWindow::GetForCurrentThread()->PointerCursor = nullptr; - } else { CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); } diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp index 207b0a1168..7cf9738f13 100644 --- a/platform/windows/context_gl_windows.cpp +++ b/platform/windows/context_gl_windows.cpp @@ -94,7 +94,7 @@ void ContextGL_Windows::swap_buffers() { if (vsync_via_compositor_now != vsync_via_compositor) { // The previous frame had a different operating mode than this - // frame. Set the 'vsync_via_compositor' member variable and the + // frame. Set the 'vsync_via_compositor' member variable and the // OpenGL swap interval to their proper values. set_use_vsync(true); } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 4dd3151eb3..f16595f379 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -84,7 +84,8 @@ void DisplayServerWindows::alert(const String &p_alert, const String &p_title) { } void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { - if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) { + if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { + // Mouse is grabbed (captured or confined). WindowData &wd = windows[MAIN_WINDOW_ID]; RECT clipRect; @@ -100,11 +101,12 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { SetCapture(wd.hWnd); } } else { + // Mouse is free to move around (not captured or confined). ReleaseCapture(); ClipCursor(nullptr); } - if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_HIDDEN) { + if (p_mode == MOUSE_MODE_HIDDEN || p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { if (hCursor == nullptr) { hCursor = SetCursor(nullptr); } else { @@ -715,7 +717,7 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window MoveWindow(wd.hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); #endif // Don't let the mouse leave the window when moved - if (mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT rect; GetClientRect(wd.hWnd, &rect); ClientToScreen(wd.hWnd, (POINT *)&rect.left); @@ -841,7 +843,7 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo MoveWindow(wd.hWnd, rect.left, rect.top, w, h, TRUE); // Don't let the mouse leave the window when resizing to a smaller resolution - if (mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT crect; GetClientRect(wd.hWnd, &crect); ClientToScreen(wd.hWnd, (POINT *)&crect.left); @@ -1889,7 +1891,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Run a timer to prevent event catching warning if the focused window is closing. windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); } - return 0; // Return To The Message Loop + return 0; // Return To The Message Loop } case WM_GETMINMAXINFO: { if (windows[window_id].resizable && !windows[window_id].fullscreen) { @@ -2189,8 +2191,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode. - if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) + if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) { break; + } Ref<InputEventMouseMotion> mm; mm.instance(); @@ -2294,8 +2297,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode. - if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) + if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) { break; + } Ref<InputEventMouseMotion> mm; mm.instance(); @@ -2427,20 +2431,23 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_MOUSEWHEEL: { mb->set_pressed(true); int motion = (short)HIWORD(wParam); - if (!motion) + if (!motion) { return 0; + } - if (motion > 0) + if (motion > 0) { mb->set_button_index(MOUSE_BUTTON_WHEEL_UP); - else + } else { mb->set_button_index(MOUSE_BUTTON_WHEEL_DOWN); + } } break; case WM_MOUSEHWHEEL: { mb->set_pressed(true); int motion = (short)HIWORD(wParam); - if (!motion) + if (!motion) { return 0; + } if (motion < 0) { mb->set_button_index(MOUSE_BUTTON_WHEEL_LEFT); @@ -2452,24 +2459,27 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_XBUTTONDOWN: { mb->set_pressed(true); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } } break; case WM_XBUTTONUP: { mb->set_pressed(false); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } } break; case WM_XBUTTONDBLCLK: { mb->set_pressed(true); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } mb->set_double_click(true); } break; default: { @@ -2481,10 +2491,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_shift_pressed((wParam & MK_SHIFT) != 0); mb->set_alt_pressed(alt_mem); //mb->is_alt_pressed()=(wParam&MK_MENU)!=0; - if (mb->is_pressed()) + if (mb->is_pressed()) { last_button_state |= (1 << (mb->get_button_index() - 1)); - else + } else { last_button_state &= ~(1 << (mb->get_button_index() - 1)); + } mb->set_button_mask(last_button_state); mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); @@ -2726,7 +2737,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_SETCURSOR: { if (LOWORD(lParam) == HTCLIENT) { - if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED)) { + if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN)) { //Hide the cursor if (hCursor == nullptr) { hCursor = SetCursor(nullptr); diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index 857c6a88f1..bb855e4ac8 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -40,13 +40,13 @@ <DisplayString Condition="type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString> <DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString> <DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString> - <DisplayString Condition="type == Variant::TRANSFORM">{_data._transform}</DisplayString> + <DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform}</DisplayString> <DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString> - <DisplayString Condition="type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString> + <DisplayString Condition="type == Variant::QUATERNION">{*(Quaternion *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::RID">{*(::RID *)_data._mem}</DisplayString> @@ -72,13 +72,13 @@ <Item Name="[value]" Condition="type == Variant::TRANSFORM2D">_data._transform2d</Item> <Item Name="[value]" Condition="type == Variant::AABB">_data._aabb</Item> <Item Name="[value]" Condition="type == Variant::BASIS">_data._basis</Item> - <Item Name="[value]" Condition="type == Variant::TRANSFORM">_data._transform</Item> + <Item Name="[value]" Condition="type == Variant::TRANSFORM3D">_data._transform</Item> <Item Name="[value]" Condition="type == Variant::STRING">*(String *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::VECTOR2">*(Vector2 *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::RECT2">*(Rect2 *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::VECTOR3">*(Vector3 *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::PLANE">*(Plane *)_data._mem</Item> - <Item Name="[value]" Condition="type == Variant::QUAT">*(Quat *)_data._mem</Item> + <Item Name="[value]" Condition="type == Variant::QUATERNION">*(Quaternion *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::COLOR">*(Color *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item> <Item Name="[value]" Condition="type == Variant::RID">*(::RID *)_data._mem</Item> @@ -128,8 +128,8 @@ </Expand> </Type> - <Type Name="Quat"> - <DisplayString>Quat {{{x},{y},{z},{w}}}</DisplayString> + <Type Name="Quaternion"> + <DisplayString>Quaternion {{{x},{y},{z},{w}}}</DisplayString> <Expand> <Item Name="x">x</Item> <Item Name="y">y</Item> diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index de648d404c..a633923be7 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -408,6 +408,10 @@ void CollisionObject2D::set_only_update_transform_changes(bool p_enable) { only_update_transform_changes = p_enable; } +bool CollisionObject2D::is_only_update_transform_changes_enabled() const { + return only_update_transform_changes; +} + void CollisionObject2D::_update_pickable() { if (!is_inside_tree()) { return; diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index bb1a9dfcf5..e10f3097d9 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -62,7 +62,7 @@ class CollisionObject2D : public Node2D { int total_subshapes = 0; Map<uint32_t, ShapeData> shapes; - bool only_update_transform_changes = false; //this is used for sync physics in KinematicBody + bool only_update_transform_changes = false; //this is used for sync physics in CharacterBody2D protected: CollisionObject2D(RID p_rid, bool p_area); @@ -77,6 +77,7 @@ protected: void _mouse_exit(); void set_only_update_transform_changes(bool p_enable); + bool is_only_update_transform_changes_enabled() const; public: void set_collision_layer(uint32_t p_layer); diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index a69ef73a54..2a2fde80e2 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -244,7 +244,7 @@ TypedArray<String> CollisionPolygon2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject2D>(get_parent())) { - warnings.push_back(TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape.")); } int polygon_count = polygon.size(); diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index d9009ef85c..60780f1cc3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -181,7 +181,7 @@ TypedArray<String> CollisionShape2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject2D>(get_parent())) { - warnings.push_back(TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape.")); } if (!shape.is_valid()) { warnings.push_back(TTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!")); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 066835ef0a..d7404ff479 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -115,7 +115,7 @@ void GPUParticles2D::set_use_local_coordinates(bool p_enable) { void GPUParticles2D::_update_particle_emission_transform() { Transform2D xf2d = get_global_transform(); - Transform xf; + Transform3D xf; xf.basis.set_axis(0, Vector3(xf2d.get_axis(0).x, xf2d.get_axis(0).y, 0)); xf.basis.set_axis(1, Vector3(xf2d.get_axis(1).x, xf2d.get_axis(1).y, 0)); xf.set_origin(Vector3(xf2d.get_origin().x, xf2d.get_origin().y, 0)); @@ -406,9 +406,9 @@ void GPUParticles2D::_notification(int p_what) { RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); - Vector<Transform> xforms; + Vector<Transform3D> xforms; for (int i = 0; i <= trail_sections; i++) { - Transform xform; + Transform3D xform; /* xform.origin.y = depth / 2.0 - size.height * float(i); xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y */ @@ -446,7 +446,7 @@ void GPUParticles2D::_notification(int p_what) { arr[RS::ARRAY_INDEX] = indices; RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); - RS::get_singleton()->particles_set_trail_bind_poses(particles, Vector<Transform>()); + RS::get_singleton()->particles_set_trail_bind_poses(particles, Vector<Transform3D>()); } RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 8afc43ddc9..049d121213 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -391,6 +391,15 @@ Point2 Node2D::to_global(Point2 p_local) const { return get_global_transform().xform(p_local); } +void Node2D::set_y_sort_enabled(bool p_enabled) { + y_sort_enabled = p_enabled; + RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_enabled); +} + +bool Node2D::is_y_sort_enabled() const { + return y_sort_enabled; +} + void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_position", "position"), &Node2D::set_position); ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Node2D::set_rotation); @@ -437,6 +446,9 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_z_as_relative", "enable"), &Node2D::set_z_as_relative); ClassDB::bind_method(D_METHOD("is_z_relative"), &Node2D::is_z_relative); + ClassDB::bind_method(D_METHOD("set_y_sort_enabled", "enabled"), &Node2D::set_y_sort_enabled); + ClassDB::bind_method(D_METHOD("is_y_sort_enabled"), &Node2D::is_y_sort_enabled); + ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); @@ -454,7 +466,8 @@ void Node2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_scale", PROPERTY_HINT_NONE, "", 0), "set_global_scale", "get_global_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); - ADD_GROUP("Z Index", ""); + ADD_GROUP("Ordering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "y_sort_enabled"), "set_y_sort_enabled", "is_y_sort_enabled"); } diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 358b7e6520..339efd9179 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -42,6 +42,7 @@ class Node2D : public CanvasItem { real_t skew = 0.0; int z_index = 0; bool z_relative = true; + bool y_sort_enabled = false; Transform2D _mat; @@ -117,6 +118,9 @@ public: void set_z_as_relative(bool p_enabled); bool is_z_relative() const; + virtual void set_y_sort_enabled(bool p_enabled); + virtual bool is_y_sort_enabled() const; + Transform2D get_relative_transform_to_parent(const Node *p_parent) const; Transform2D get_transform() const override; diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp new file mode 100644 index 0000000000..0c1be16174 --- /dev/null +++ b/scene/2d/physical_bone_2d.cpp @@ -0,0 +1,303 @@ +/*************************************************************************/ +/* physical_bone_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "physical_bone_2d.h" + +void PhysicalBone2D::_notification(int p_what) { + if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { + // Position the RigidBody in the correct position + if (follow_bone_when_simulating) { + _position_at_bone2d(); + } + + // Keep the child joint in the correct position. + if (child_joint && auto_configure_joint) { + child_joint->set_global_position(get_global_position()); + } + } else if (p_what == NOTIFICATION_READY) { + _find_skeleton_parent(); + _find_joint_child(); + + // Configure joint + if (child_joint && auto_configure_joint) { + _auto_configure_joint(); + } + + // Simulate physics if set + if (simulate_physics) { + _start_physics_simulation(); + } else { + _stop_physics_simulation(); + } + + set_physics_process_internal(true); + } +} + +void PhysicalBone2D::_position_at_bone2d() { + // Reset to Bone2D position + if (parent_skeleton) { + Bone2D *bone_to_use = parent_skeleton->get_bone(bone2d_index); + ERR_FAIL_COND_MSG(bone_to_use == nullptr, "It's not possible to position the bone with ID: " + itos(bone2d_index)); + set_global_transform(bone_to_use->get_global_transform()); + } +} + +void PhysicalBone2D::_find_skeleton_parent() { + Node *current_parent = get_parent(); + + while (current_parent != nullptr) { + Skeleton2D *potential_skeleton = Object::cast_to<Skeleton2D>(current_parent); + if (potential_skeleton) { + parent_skeleton = potential_skeleton; + break; + } else { + PhysicalBone2D *potential_parent_bone = Object::cast_to<PhysicalBone2D>(current_parent); + if (potential_parent_bone) { + current_parent = potential_parent_bone->get_parent(); + } else { + current_parent = nullptr; + } + } + } +} + +void PhysicalBone2D::_find_joint_child() { + for (int i = 0; i < get_child_count(); i++) { + Node *child_node = get_child(i); + Joint2D *potential_joint = Object::cast_to<Joint2D>(child_node); + if (potential_joint) { + child_joint = potential_joint; + break; + } + } +} + +TypedArray<String> PhysicalBone2D::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (!parent_skeleton) { + warnings.push_back(TTR("A PhysicalBone2D only works with a Skeleton2D or another PhysicalBone2D as a parent node!")); + } + if (parent_skeleton && bone2d_index <= -1) { + warnings.push_back(TTR("A PhysicalBone2D needs to be assigned to a Bone2D node in order to function! Please set a Bone2D node in the inspector.")); + } + if (!child_joint) { + PhysicalBone2D *parent_bone = Object::cast_to<PhysicalBone2D>(get_parent()); + if (parent_bone) { + warnings.push_back(TTR("A PhysicalBone2D node should have a Joint2D-based child node to keep bones connected! Please add a Joint2D-based node as a child to this node!")); + } + } + + return warnings; +} + +void PhysicalBone2D::_auto_configure_joint() { + if (!auto_configure_joint) { + return; + } + + if (child_joint) { + // Node A = parent | Node B = this node + Node *parent_node = get_parent(); + PhysicalBone2D *potential_parent_bone = Object::cast_to<PhysicalBone2D>(parent_node); + + if (potential_parent_bone) { + child_joint->set_node_a(child_joint->get_path_to(potential_parent_bone)); + child_joint->set_node_b(child_joint->get_path_to(this)); + } else { + WARN_PRINT("Cannot setup joint without a parent PhysicalBone2D node."); + } + + // Place the child joint at this node's position. + child_joint->set_global_position(get_global_position()); + } +} + +void PhysicalBone2D::_start_physics_simulation() { + if (_internal_simulate_physics) { + return; + } + + // Reset to Bone2D position + _position_at_bone2d(); + + // Apply the layers and masks + PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); + PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); + + // Apply the correct mode + RigidBody2D::Mode rigid_mode = get_mode(); + if (rigid_mode == RigidBody2D::MODE_STATIC) { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_STATIC); + } else if (rigid_mode == RigidBody2D::MODE_DYNAMIC) { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_DYNAMIC); + } else if (rigid_mode == RigidBody2D::MODE_KINEMATIC) { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_KINEMATIC); + } else if (rigid_mode == RigidBody2D::MODE_DYNAMIC_LOCKED) { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_DYNAMIC_LOCKED); + } else { + // Default to Rigid + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_DYNAMIC); + } + + _internal_simulate_physics = true; + set_physics_process_internal(true); +} + +void PhysicalBone2D::_stop_physics_simulation() { + if (_internal_simulate_physics) { + _internal_simulate_physics = false; + + // Reset to Bone2D position + _position_at_bone2d(); + + set_physics_process_internal(false); + PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), 0); + PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), 0); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_STATIC); + } +} + +Joint2D *PhysicalBone2D::get_joint() const { + return child_joint; +} + +bool PhysicalBone2D::get_auto_configure_joint() const { + return auto_configure_joint; +} + +void PhysicalBone2D::set_auto_configure_joint(bool p_auto_configure) { + auto_configure_joint = p_auto_configure; + _auto_configure_joint(); +} + +void PhysicalBone2D::set_simulate_physics(bool p_simulate) { + if (p_simulate == simulate_physics) { + return; + } + simulate_physics = p_simulate; + + if (simulate_physics) { + _start_physics_simulation(); + } else { + _stop_physics_simulation(); + } +} + +bool PhysicalBone2D::get_simulate_physics() const { + return simulate_physics; +} + +bool PhysicalBone2D::is_simulating_physics() const { + return _internal_simulate_physics; +} + +void PhysicalBone2D::set_bone2d_nodepath(const NodePath &p_nodepath) { + bone2d_nodepath = p_nodepath; + notify_property_list_changed(); +} + +NodePath PhysicalBone2D::get_bone2d_nodepath() const { + return bone2d_nodepath; +} + +void PhysicalBone2D::set_bone2d_index(int p_bone_idx) { + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (!is_inside_tree()) { + bone2d_index = p_bone_idx; + return; + } + + if (parent_skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, parent_skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + bone2d_index = p_bone_idx; + + bone2d_nodepath = get_path_to(parent_skeleton->get_bone(bone2d_index)); + } else { + WARN_PRINT("Cannot verify bone index..."); + bone2d_index = p_bone_idx; + } + + notify_property_list_changed(); +} + +int PhysicalBone2D::get_bone2d_index() const { + return bone2d_index; +} + +void PhysicalBone2D::set_follow_bone_when_simulating(bool p_follow_bone) { + follow_bone_when_simulating = p_follow_bone; + + if (_internal_simulate_physics) { + _stop_physics_simulation(); + _start_physics_simulation(); + } +} + +bool PhysicalBone2D::get_follow_bone_when_simulating() const { + return follow_bone_when_simulating; +} + +void PhysicalBone2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_joint"), &PhysicalBone2D::get_joint); + ClassDB::bind_method(D_METHOD("get_auto_configure_joint"), &PhysicalBone2D::get_auto_configure_joint); + ClassDB::bind_method(D_METHOD("set_auto_configure_joint", "auto_configure_joint"), &PhysicalBone2D::set_auto_configure_joint); + + ClassDB::bind_method(D_METHOD("set_simulate_physics", "simulate_physics"), &PhysicalBone2D::set_simulate_physics); + ClassDB::bind_method(D_METHOD("get_simulate_physics"), &PhysicalBone2D::get_simulate_physics); + ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone2D::is_simulating_physics); + + ClassDB::bind_method(D_METHOD("set_bone2d_nodepath", "nodepath"), &PhysicalBone2D::set_bone2d_nodepath); + ClassDB::bind_method(D_METHOD("get_bone2d_nodepath"), &PhysicalBone2D::get_bone2d_nodepath); + ClassDB::bind_method(D_METHOD("set_bone2d_index", "bone_index"), &PhysicalBone2D::set_bone2d_index); + ClassDB::bind_method(D_METHOD("get_bone2d_index"), &PhysicalBone2D::get_bone2d_index); + ClassDB::bind_method(D_METHOD("set_follow_bone_when_simulating", "follow_bone"), &PhysicalBone2D::set_follow_bone_when_simulating); + ClassDB::bind_method(D_METHOD("get_follow_bone_when_simulating"), &PhysicalBone2D::get_follow_bone_when_simulating); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "bone2d_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D"), "set_bone2d_nodepath", "get_bone2d_nodepath"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bone2d_index", PROPERTY_HINT_RANGE, "-1, 1000, 1"), "set_bone2d_index", "get_bone2d_index"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_configure_joint"), "set_auto_configure_joint", "get_auto_configure_joint"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "simulate_physics"), "set_simulate_physics", "get_simulate_physics"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_bone_when_simulating"), "set_follow_bone_when_simulating", "get_follow_bone_when_simulating"); +} + +PhysicalBone2D::PhysicalBone2D() { + // Stop the RigidBody from executing its force integration. + PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), 0); + PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), 0); + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_STATIC); + + child_joint = nullptr; +} + +PhysicalBone2D::~PhysicalBone2D() { +} diff --git a/scene/2d/physical_bone_2d.h b/scene/2d/physical_bone_2d.h new file mode 100644 index 0000000000..d650a0426f --- /dev/null +++ b/scene/2d/physical_bone_2d.h @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* physical_bone_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef PHYSICAL_BONE_2D_H +#define PHYSICAL_BONE_2D_H + +#include "scene/2d/joints_2d.h" +#include "scene/2d/physics_body_2d.h" + +#include "scene/2d/skeleton_2d.h" + +class PhysicalBone2D : public RigidBody2D { + GDCLASS(PhysicalBone2D, RigidBody2D); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +private: + Skeleton2D *parent_skeleton; + int bone2d_index = -1; + NodePath bone2d_nodepath; + bool follow_bone_when_simulating = false; + + Joint2D *child_joint; + bool auto_configure_joint = true; + + bool simulate_physics = false; + bool _internal_simulate_physics = false; + + void _find_skeleton_parent(); + void _find_joint_child(); + void _auto_configure_joint(); + + void _start_physics_simulation(); + void _stop_physics_simulation(); + void _position_at_bone2d(); + +public: + Joint2D *get_joint() const; + bool get_auto_configure_joint() const; + void set_auto_configure_joint(bool p_auto_configure); + + void set_simulate_physics(bool p_simulate); + bool get_simulate_physics() const; + bool is_simulating_physics() const; + + void set_bone2d_nodepath(const NodePath &p_nodepath); + NodePath get_bone2d_nodepath() const; + void set_bone2d_index(int p_bone_idx); + int get_bone2d_index() const; + void set_follow_bone_when_simulating(bool p_follow); + bool get_follow_bone_when_simulating() const; + + TypedArray<String> get_configuration_warnings() const override; + + PhysicalBone2D(); + ~PhysicalBone2D(); +}; + +#endif // PHYSICAL_BONE_2D_H diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 4f52f62e99..4b72043a46 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -38,10 +38,10 @@ #include "core/templates/rid.h" #include "scene/scene_string_names.h" -void PhysicsBody2D::_notification(int p_what) { -} - void PhysicsBody2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.08)); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.08)); + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody2D::remove_collision_exception_with); @@ -53,6 +53,56 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : set_pickable(false); } +PhysicsBody2D::~PhysicsBody2D() { + if (motion_cache.is_valid()) { + motion_cache->owner = nullptr; + } +} + +Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) { + PhysicsServer2D::MotionResult result; + + if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; + } + + motion_cache->result = result; + + return motion_cache; + } + + return Ref<KinematicCollision2D>(); +} + +bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) { + if (is_only_update_transform_changes_enabled()) { + ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation."); + } + Transform2D gt = get_global_transform(); + bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes); + + if (!p_test_only) { + gt.elements[2] += r_result.motion; + set_global_transform(gt); + } + + return colliding; +} + +bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) { + ERR_FAIL_COND_V(!is_inside_tree(), false); + + PhysicsServer2D::MotionResult *r = nullptr; + if (r_collision.is_valid()) { + // Needs const_cast because method bindings don't support non-const Ref. + r = const_cast<PhysicsServer2D::MotionResult *>(&r_collision->result); + } + + return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes); +} + TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); @@ -83,12 +133,22 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) { void StaticBody2D::set_constant_linear_velocity(const Vector2 &p_vel) { constant_linear_velocity = p_vel; - PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + } } void StaticBody2D::set_constant_angular_velocity(real_t p_vel) { constant_angular_velocity = p_vel; - PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + } } Vector2 StaticBody2D::get_constant_linear_velocity() const { @@ -118,27 +178,74 @@ Ref<PhysicsMaterial> StaticBody2D::get_physics_material_override() const { return physics_material_override; } +void StaticBody2D::set_kinematic_motion_enabled(bool p_enabled) { + if (p_enabled == kinematic_motion) { + return; + } + + kinematic_motion = p_enabled; + + if (kinematic_motion) { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_KINEMATIC); + } else { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_STATIC); + } + + _update_kinematic_motion(); +} + +bool StaticBody2D::is_kinematic_motion_enabled() const { + return kinematic_motion; +} + +void StaticBody2D::_notification(int p_what) { + if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + ERR_FAIL_COND(!kinematic_motion); + + real_t delta_time = get_physics_process_delta_time(); + + Transform2D new_transform = get_global_transform(); + + new_transform.translate(constant_linear_velocity * delta_time); + new_transform.set_rotation(new_transform.get_rotation() + constant_angular_velocity * delta_time); + + PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_TRANSFORM, new_transform); + + // Propagate transform change to node. + set_block_transform_notify(true); + set_global_transform(new_transform); + set_block_transform_notify(false); + } +} + void StaticBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody2D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody2D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody2D::get_constant_angular_velocity); + ClassDB::bind_method(D_METHOD("set_kinematic_motion_enabled", "enabled"), &StaticBody2D::set_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("is_kinematic_motion_enabled"), &StaticBody2D::is_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody2D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody2D::get_physics_material_override); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "kinematic_motion"), "set_kinematic_motion_enabled", "is_kinematic_motion_enabled"); } StaticBody2D::StaticBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) { } -StaticBody2D::~StaticBody2D() { -} - void StaticBody2D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, 0); @@ -149,6 +256,23 @@ void StaticBody2D::_reload_physics_characteristics() { } } +void StaticBody2D::_update_kinematic_motion() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + if (kinematic_motion) { + if (!Math::is_zero_approx(constant_angular_velocity) || !constant_linear_velocity.is_equal_approx(Vector2())) { + set_physics_process_internal(true); + return; + } + } + + set_physics_process_internal(false); +} + void RigidBody2D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -262,14 +386,6 @@ struct _RigidBody2DInOut { int local_shape = 0; }; -bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { - PhysicsServer2D::MotionResult *r = nullptr; - if (p_result.is_valid()) { - r = p_result->get_result_ptr(); - } - return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r); -} - void RigidBody2D::_direct_state_changed(Object *p_state) { #ifdef DEBUG_ENABLED state = Object::cast_to<PhysicsDirectBodyState2D>(p_state); @@ -378,8 +494,8 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { void RigidBody2D::set_mode(Mode p_mode) { mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_RIGID); + case MODE_DYNAMIC: { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_DYNAMIC); } break; case MODE_STATIC: { PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_STATIC); @@ -389,8 +505,8 @@ void RigidBody2D::set_mode(Mode p_mode) { PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_KINEMATIC); } break; - case MODE_CHARACTER: { - PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_CHARACTER); + case MODE_DYNAMIC_LOCKED: { + PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_DYNAMIC_LOCKED); } break; } @@ -666,8 +782,8 @@ TypedArray<String> RigidBody2D::get_configuration_warnings() const { TypedArray<String> warnings = CollisionObject2D::get_configuration_warnings(); - if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) { - warnings.push_back(TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + if ((get_mode() == MODE_DYNAMIC || get_mode() == MODE_DYNAMIC_LOCKED) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) { + warnings.push_back(TTR("Size changes to RigidBody2D (in dynamic modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -734,13 +850,11 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody2D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody2D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("test_motion", "motion", "infinite_inertia", "margin", "result"), &RigidBody2D::_test_motion, DEFVAL(true), DEFVAL(0.08), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState2D"))); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); @@ -767,9 +881,9 @@ void RigidBody2D::_bind_methods() { ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); - BIND_ENUM_CONSTANT(MODE_RIGID); + BIND_ENUM_CONSTANT(MODE_DYNAMIC); BIND_ENUM_CONSTANT(MODE_STATIC); - BIND_ENUM_CONSTANT(MODE_CHARACTER); + BIND_ENUM_CONSTANT(MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(MODE_KINEMATIC); BIND_ENUM_CONSTANT(CCD_MODE_DISABLED); @@ -778,7 +892,7 @@ void RigidBody2D::_bind_methods() { } RigidBody2D::RigidBody2D() : - PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { + PhysicsBody2D(PhysicsServer2D::BODY_MODE_DYNAMIC) { PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &RigidBody2D::_direct_state_changed)); } @@ -800,95 +914,13 @@ void RigidBody2D::_reload_physics_characteristics() { ////////////////////////// -Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; - - if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { - if (motion_cache.is_null()) { - motion_cache.instance(); - motion_cache->owner = this; - } - - motion_cache->collision = col; - - return motion_cache; - } - - return Ref<KinematicCollision2D>(); -} - -bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { - PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays - - Transform2D gt = get_global_transform(); - - Vector2 recover; - int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); - int deepest = -1; - real_t deepest_depth; - for (int i = 0; i < hits; i++) { - if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { - deepest = i; - deepest_depth = sep_res[i].collision_depth; - } - } - - gt.elements[2] += recover; - set_global_transform(gt); - - if (deepest != -1) { - r_collision.collider = sep_res[deepest].collider_id; - r_collision.collider_metadata = sep_res[deepest].collider_metadata; - r_collision.collider_shape = sep_res[deepest].collider_shape; - r_collision.collider_vel = sep_res[deepest].collider_velocity; - r_collision.collision = sep_res[deepest].collision_point; - r_collision.normal = sep_res[deepest].collision_normal; - r_collision.local_shape = sep_res[deepest].collision_local_shape; - r_collision.travel = recover; - r_collision.remainder = Vector2(); - - return true; - } else { - return false; - } -} - -bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - if (sync_to_physics) { - ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation."); - } - Transform2D gt = get_global_transform(); - PhysicsServer2D::MotionResult result; - bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); - - if (colliding) { - r_collision.collider_metadata = result.collider_metadata; - r_collision.collider_shape = result.collider_shape; - r_collision.collider_vel = result.collider_velocity; - r_collision.collision = result.collision_point; - r_collision.normal = result.collision_normal; - r_collision.collider = result.collider_id; - r_collision.collider_rid = result.collider; - r_collision.travel = result.motion; - r_collision.remainder = result.remainder; - r_collision.local_shape = result.collision_local_shape; - } - - if (!p_test_only) { - gt.elements[2] += result.motion; - set_global_transform(gt); - } - - return colliding; -} - //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector2 body_velocity = p_linear_velocity; - Vector2 body_velocity_normal = body_velocity.normalized(); - Vector2 up_direction = p_up_direction.normalized(); +void CharacterBody2D::move_and_slide() { + Vector2 body_velocity_normal = linear_velocity.normalized(); + + bool was_on_floor = on_floor; Vector2 current_floor_velocity = floor_velocity; if (on_floor && on_floor_body.is_valid()) { @@ -900,69 +932,71 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector2 motion = (current_floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); + Vector2 motion = (current_floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_normal = Vector2(); floor_velocity = Vector2(); - while (p_max_slides) { - Collision collision; + int slide_count = max_slides; + while (slide_count) { + PhysicsServer2D::MotionResult result; bool found_collision = false; for (int i = 0; i < 2; ++i) { bool collided; if (i == 0) { //collide - collided = move_and_collide(motion, p_infinite_inertia, collision); + collided = move_and_collide(motion, infinite_inertia, result, margin); if (!collided) { motion = Vector2(); //clear because no collision happened and motion completed } } else { //separate raycasts (if any) - collided = separate_raycast_shapes(p_infinite_inertia, collision); + collided = separate_raycast_shapes(result); if (collided) { - collision.remainder = motion; //keep - collision.travel = Vector2(); + result.remainder = motion; //keep + result.motion = Vector2(); } } if (collided) { found_collision = true; - colliders.push_back(collision); - motion = collision.remainder; + motion_results.push_back(result); + motion = result.remainder; if (up_direction == Vector2()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; - floor_normal = collision.normal; - on_floor_body = collision.collider_rid; - floor_velocity = collision.collider_vel; + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; - if (p_stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) { + if (stop_on_slope) { + if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) { Transform2D gt = get_global_transform(); - gt.elements[2] -= collision.travel.slide(up_direction); + gt.elements[2] -= result.motion.slide(up_direction); set_global_transform(gt); - return Vector2(); + linear_velocity = Vector2(); + return; } } - } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; } } - motion = motion.slide(collision.normal); - body_velocity = body_velocity.slide(collision.normal); + motion = motion.slide(result.collision_normal); + linear_velocity = linear_velocity.slide(result.collision_normal); } } @@ -970,36 +1004,28 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const break; } - --p_max_slides; + --slide_count; } - return body_velocity; -} - -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector2 up_direction = p_up_direction.normalized(); - bool was_on_floor = on_floor; - - Vector2 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); - if (!was_on_floor || p_snap == Vector2()) { - return ret; + if (!was_on_floor || snap == Vector2()) { + return; } - Collision col; + // Apply snap. Transform2D gt = get_global_transform(); - - if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + PhysicsServer2D::MotionResult result; + if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { bool apply = true; if (up_direction != Vector2()) { - if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { on_floor = true; - floor_normal = col.normal; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; - if (p_stop_on_slope) { + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = up_direction * up_direction.dot(col.travel); + result.motion = up_direction * up_direction.dot(result.motion); } } else { @@ -1008,59 +1034,87 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci } if (apply) { - gt.elements[2] += col.travel; + gt.elements[2] += result.motion; set_global_transform(gt); } } - - return ret; } -bool KinematicBody2D::is_on_floor() const { - return on_floor; -} +bool CharacterBody2D::separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result) { + PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays -bool KinematicBody2D::is_on_wall() const { - return on_wall; + Transform2D gt = get_global_transform(); + + Vector2 recover; + int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin); + int deepest = -1; + real_t deepest_depth; + for (int i = 0; i < hits; i++) { + if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { + deepest = i; + deepest_depth = sep_res[i].collision_depth; + } + } + + gt.elements[2] += recover; + set_global_transform(gt); + + if (deepest != -1) { + r_result.collider_id = sep_res[deepest].collider_id; + r_result.collider_metadata = sep_res[deepest].collider_metadata; + r_result.collider_shape = sep_res[deepest].collider_shape; + r_result.collider_velocity = sep_res[deepest].collider_velocity; + r_result.collision_point = sep_res[deepest].collision_point; + r_result.collision_normal = sep_res[deepest].collision_normal; + r_result.collision_local_shape = sep_res[deepest].collision_local_shape; + r_result.motion = recover; + r_result.remainder = Vector2(); + + return true; + } else { + return false; + } } -bool KinematicBody2D::is_on_ceiling() const { - return on_ceiling; +const Vector2 &CharacterBody2D::get_linear_velocity() const { + return linear_velocity; } -Vector2 KinematicBody2D::get_floor_normal() const { - return floor_normal; +void CharacterBody2D::set_linear_velocity(const Vector2 &p_velocity) { + linear_velocity = p_velocity; } -Vector2 KinematicBody2D::get_floor_velocity() const { - return floor_velocity; +bool CharacterBody2D::is_on_floor() const { + return on_floor; } -bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); +bool CharacterBody2D::is_on_wall() const { + return on_wall; +} - return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin); +bool CharacterBody2D::is_on_ceiling() const { + return on_ceiling; } -void KinematicBody2D::set_safe_margin(real_t p_margin) { - margin = p_margin; +Vector2 CharacterBody2D::get_floor_normal() const { + return floor_normal; } -real_t KinematicBody2D::get_safe_margin() const { - return margin; +Vector2 CharacterBody2D::get_floor_velocity() const { + return floor_velocity; } -int KinematicBody2D::get_slide_count() const { - return colliders.size(); +int CharacterBody2D::get_slide_count() const { + return motion_results.size(); } -KinematicBody2D::Collision KinematicBody2D::get_slide_collision(int p_bounce) const { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); - return colliders[p_bounce]; +PhysicsServer2D::MotionResult CharacterBody2D::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), PhysicsServer2D::MotionResult()); + return motion_results[p_bounce]; } -Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision2D>()); +Ref<KinematicCollision2D> CharacterBody2D::_get_slide_collision(int p_bounce) { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), Ref<KinematicCollision2D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); } @@ -1070,11 +1124,11 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { slide_colliders.write[p_bounce]->owner = this; } - slide_colliders.write[p_bounce]->collision = colliders[p_bounce]; + slide_colliders.write[p_bounce]->result = motion_results[p_bounce]; return slide_colliders[p_bounce]; } -void KinematicBody2D::set_sync_to_physics(bool p_enable) { +void CharacterBody2D::set_sync_to_physics(bool p_enable) { if (sync_to_physics == p_enable) { return; } @@ -1085,7 +1139,7 @@ void KinematicBody2D::set_sync_to_physics(bool p_enable) { } if (p_enable) { - PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &KinematicBody2D::_direct_state_changed)); + PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &CharacterBody2D::_direct_state_changed)); set_only_update_transform_changes(true); set_notify_local_transform(true); } else { @@ -1095,11 +1149,11 @@ void KinematicBody2D::set_sync_to_physics(bool p_enable) { } } -bool KinematicBody2D::is_sync_to_physics_enabled() const { +bool CharacterBody2D::is_sync_to_physics_enabled() const { return sync_to_physics; } -void KinematicBody2D::_direct_state_changed(Object *p_state) { +void CharacterBody2D::_direct_state_changed(Object *p_state) { if (!sync_to_physics) { return; } @@ -1113,7 +1167,71 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) { set_notify_local_transform(true); } -void KinematicBody2D::_notification(int p_what) { +void CharacterBody2D::set_safe_margin(real_t p_margin) { + margin = p_margin; +} + +real_t CharacterBody2D::get_safe_margin() const { + return margin; +} + +bool CharacterBody2D::is_stop_on_slope_enabled() const { + return stop_on_slope; +} + +void CharacterBody2D::set_stop_on_slope_enabled(bool p_enabled) { + stop_on_slope = p_enabled; +} + +bool CharacterBody2D::is_infinite_inertia_enabled() const { + return infinite_inertia; +} +void CharacterBody2D::set_infinite_inertia_enabled(bool p_enabled) { + infinite_inertia = p_enabled; +} + +int CharacterBody2D::get_max_slides() const { + return max_slides; +} + +void CharacterBody2D::set_max_slides(int p_max_slides) { + ERR_FAIL_COND(p_max_slides > 0); + max_slides = p_max_slides; +} + +real_t CharacterBody2D::get_floor_max_angle() const { + return floor_max_angle; +} + +void CharacterBody2D::set_floor_max_angle(real_t p_radians) { + floor_max_angle = p_radians; +} + +real_t CharacterBody2D::get_floor_max_angle_degrees() const { + return Math::rad2deg(floor_max_angle); +} + +void CharacterBody2D::set_floor_max_angle_degrees(real_t p_degrees) { + floor_max_angle = Math::deg2rad(p_degrees); +} + +const Vector2 &CharacterBody2D::get_snap() const { + return snap; +} + +void CharacterBody2D::set_snap(const Vector2 &p_snap) { + snap = p_snap; +} + +const Vector2 &CharacterBody2D::get_up_direction() const { + return up_direction; +} + +void CharacterBody2D::set_up_direction(const Vector2 &p_up_direction) { + up_direction = p_up_direction.normalized(); +} + +void CharacterBody2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { last_valid_transform = get_global_transform(); @@ -1122,7 +1240,7 @@ void KinematicBody2D::_notification(int p_what) { on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_velocity = Vector2(); } @@ -1137,47 +1255,58 @@ void KinematicBody2D::_notification(int p_what) { } } -void KinematicBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor); - ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling); - ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall); - ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody2D::get_floor_normal); - ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity); +void CharacterBody2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody2D::move_and_slide); + + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody2D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody2D::get_linear_velocity); + + ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody2D::set_safe_margin); + ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody2D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody2D::is_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody2D::set_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody2D::is_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody2D::set_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides); + ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides); + ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody2D::get_floor_max_angle); + ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody2D::set_floor_max_angle); + ClassDB::bind_method(D_METHOD("get_floor_max_angle_degrees"), &CharacterBody2D::get_floor_max_angle_degrees); + ClassDB::bind_method(D_METHOD("set_floor_max_angle_degrees", "degrees"), &CharacterBody2D::set_floor_max_angle_degrees); + ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody2D::get_snap); + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody2D::set_snap); + ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody2D::get_up_direction); + ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction); + + ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody2D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_ceiling"), &CharacterBody2D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody2D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody2D::get_floor_normal); + ClassDB::bind_method(D_METHOD("get_floor_velocity"), &CharacterBody2D::get_floor_velocity); + ClassDB::bind_method(D_METHOD("get_slide_count"), &CharacterBody2D::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody2D::_get_slide_collision); + + ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &CharacterBody2D::set_sync_to_physics); + ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &CharacterBody2D::is_sync_to_physics_enabled); - ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin); - ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody2D::get_safe_margin); - - ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count); - ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision); - - ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &KinematicBody2D::set_sync_to_physics); - ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &KinematicBody2D::is_sync_to_physics_enabled); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides"), "set_max_slides", "get_max_slides"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_floor_max_angle", "get_floor_max_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle_degrees", PROPERTY_HINT_RANGE, "0,180,0.1", PROPERTY_USAGE_EDITOR), "set_floor_max_angle_degrees", "get_floor_max_angle_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "snap"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } -KinematicBody2D::KinematicBody2D() : +CharacterBody2D::CharacterBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) { - margin = 0.08; - - on_floor = false; - on_ceiling = false; - on_wall = false; - sync_to_physics = false; } -KinematicBody2D::~KinematicBody2D() { - if (motion_cache.is_valid()) { - motion_cache->owner = nullptr; - } - +CharacterBody2D::~CharacterBody2D() { for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { slide_colliders.write[i]->owner = nullptr; @@ -1188,39 +1317,39 @@ KinematicBody2D::~KinematicBody2D() { //////////////////////// Vector2 KinematicCollision2D::get_position() const { - return collision.collision; + return result.collision_point; } Vector2 KinematicCollision2D::get_normal() const { - return collision.normal; + return result.collision_normal; } Vector2 KinematicCollision2D::get_travel() const { - return collision.travel; + return result.motion; } Vector2 KinematicCollision2D::get_remainder() const { - return collision.remainder; + return result.remainder; } Object *KinematicCollision2D::get_local_shape() const { if (!owner) { return nullptr; } - uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + uint32_t ownerid = owner->shape_find_owner(result.collision_local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision2D::get_collider() const { - if (collision.collider.is_valid()) { - return ObjectDB::get_instance(collision.collider); + if (result.collider_id.is_valid()) { + return ObjectDB::get_instance(result.collider_id); } return nullptr; } ObjectID KinematicCollision2D::get_collider_id() const { - return collision.collider; + return result.collider_id; } Object *KinematicCollision2D::get_collider_shape() const { @@ -1228,7 +1357,7 @@ Object *KinematicCollision2D::get_collider_shape() const { if (collider) { CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider); if (obj2d) { - uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + uint32_t ownerid = obj2d->shape_find_owner(result.collider_shape); return obj2d->shape_owner_get_owner(ownerid); } } @@ -1237,11 +1366,11 @@ Object *KinematicCollision2D::get_collider_shape() const { } int KinematicCollision2D::get_collider_shape_index() const { - return collision.collider_shape; + return result.collider_shape; } Vector2 KinematicCollision2D::get_collider_velocity() const { - return collision.collider_vel; + return result.collider_velocity; } Variant KinematicCollision2D::get_collider_metadata() const { @@ -1273,9 +1402,3 @@ void KinematicCollision2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity"); ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); } - -KinematicCollision2D::KinematicCollision2D() { - collision.collider_shape = 0; - collision.local_shape = 0; - owner = nullptr; -} diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 47d55d11fa..cd39a1996c 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -42,17 +42,22 @@ class PhysicsBody2D : public CollisionObject2D { GDCLASS(PhysicsBody2D, CollisionObject2D); protected: - void _notification(int p_what); + static void _bind_methods(); PhysicsBody2D(PhysicsServer2D::BodyMode p_mode); - static void _bind_methods(); + Ref<KinematicCollision2D> motion_cache; + + Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.08); public: + bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false); + bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08); + TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); - PhysicsBody2D(); + virtual ~PhysicsBody2D(); }; class StaticBody2D : public PhysicsBody2D { @@ -63,7 +68,10 @@ class StaticBody2D : public PhysicsBody2D { Ref<PhysicsMaterial> physics_material_override; + bool kinematic_motion = false; + protected: + void _notification(int p_what); static void _bind_methods(); public: @@ -77,10 +85,14 @@ public: real_t get_constant_angular_velocity() const; StaticBody2D(); - ~StaticBody2D(); private: void _reload_physics_characteristics(); + + void _update_kinematic_motion(); + + void set_kinematic_motion_enabled(bool p_enabled); + bool is_kinematic_motion_enabled() const; }; class RigidBody2D : public PhysicsBody2D { @@ -88,9 +100,9 @@ class RigidBody2D : public PhysicsBody2D { public: enum Mode { - MODE_RIGID, + MODE_DYNAMIC, MODE_STATIC, - MODE_CHARACTER, + MODE_DYNAMIC_LOCKED, MODE_KINEMATIC, }; @@ -103,7 +115,7 @@ public: private: bool can_sleep = true; PhysicsDirectBodyState2D *state = nullptr; - Mode mode = MODE_RIGID; + Mode mode = MODE_DYNAMIC; real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; @@ -163,8 +175,6 @@ private: void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape); void _direct_state_changed(Object *p_state); - bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); - protected: void _notification(int p_what); static void _bind_methods(); @@ -245,62 +255,73 @@ private: VARIANT_ENUM_CAST(RigidBody2D::Mode); VARIANT_ENUM_CAST(RigidBody2D::CCDMode); -class KinematicBody2D : public PhysicsBody2D { - GDCLASS(KinematicBody2D, PhysicsBody2D); - -public: - struct Collision { - Vector2 collision; - Vector2 normal; - Vector2 collider_vel; - ObjectID collider; - RID collider_rid; - int collider_shape = 0; - Variant collider_metadata; - Vector2 remainder; - Vector2 travel; - int local_shape = 0; - }; +class CharacterBody2D : public PhysicsBody2D { + GDCLASS(CharacterBody2D, PhysicsBody2D); private: - real_t margin; + real_t margin = 0.08; + + bool stop_on_slope = false; + bool infinite_inertia = true; + int max_slides = 4; + real_t floor_max_angle = Math::deg2rad((real_t)45.0); + Vector2 snap; + Vector2 up_direction = Vector2(0.0, -1.0); + + Vector2 linear_velocity; Vector2 floor_normal; Vector2 floor_velocity; RID on_floor_body; - bool on_floor; - bool on_ceiling; - bool on_wall; - bool sync_to_physics; + bool on_floor = false; + bool on_ceiling = false; + bool on_wall = false; + bool sync_to_physics = false; - Vector<Collision> colliders; + Vector<PhysicsServer2D::MotionResult> motion_results; Vector<Ref<KinematicCollision2D>> slide_colliders; - Ref<KinematicCollision2D> motion_cache; - _FORCE_INLINE_ bool _ignores_mode(PhysicsServer2D::BodyMode) const; - - Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); + bool separate_raycast_shapes(PhysicsServer2D::MotionResult &r_result); + Transform2D last_valid_transform; void _direct_state_changed(Object *p_state); + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; + + bool is_stop_on_slope_enabled() const; + void set_stop_on_slope_enabled(bool p_enabled); + + bool is_infinite_inertia_enabled() const; + void set_infinite_inertia_enabled(bool p_enabled); + + int get_max_slides() const; + void set_max_slides(int p_max_slides); + + real_t get_floor_max_angle() const; + void set_floor_max_angle(real_t p_radians); + + real_t get_floor_max_angle_degrees() const; + void set_floor_max_angle_degrees(real_t p_degrees); + + const Vector2 &get_snap() const; + void set_snap(const Vector2 &p_snap); + + const Vector2 &get_up_direction() const; + void set_up_direction(const Vector2 &p_up_direction); + protected: void _notification(int p_what); static void _bind_methods(); public: - bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false); - - bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true); - - bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); + void move_and_slide(); - void set_safe_margin(real_t p_margin); - real_t get_safe_margin() const; + const Vector2 &get_linear_velocity() const; + void set_linear_velocity(const Vector2 &p_velocity); - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); - Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -308,21 +329,22 @@ public: Vector2 get_floor_velocity() const; int get_slide_count() const; - Collision get_slide_collision(int p_bounce) const; + PhysicsServer2D::MotionResult get_slide_collision(int p_bounce) const; void set_sync_to_physics(bool p_enable); bool is_sync_to_physics_enabled() const; - KinematicBody2D(); - ~KinematicBody2D(); + CharacterBody2D(); + ~CharacterBody2D(); }; class KinematicCollision2D : public Reference { GDCLASS(KinematicCollision2D, Reference); - KinematicBody2D *owner; - friend class KinematicBody2D; - KinematicBody2D::Collision collision; + PhysicsBody2D *owner = nullptr; + friend class PhysicsBody2D; + friend class CharacterBody2D; + PhysicsServer2D::MotionResult result; protected: static void _bind_methods(); @@ -339,8 +361,6 @@ public: int get_collider_shape_index() const; Vector2 get_collider_velocity() const; Variant get_collider_metadata() const; - - KinematicCollision2D(); }; #endif // PHYSICS_BODY_2D_H diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 5c7d65e3e0..1019f85c8a 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -36,10 +36,41 @@ const real_t DEFAULT_GIZMO_EXTENTS = 10.0; void Position2D::_draw_cross() { - real_t extents = get_gizmo_extents(); - // Colors taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`) - draw_line(Point2(-extents, 0), Point2(+extents, 0), Color(0.96, 0.20, 0.32)); - draw_line(Point2(0, -extents), Point2(0, +extents), Color(0.53, 0.84, 0.01)); + const real_t extents = get_gizmo_extents(); + + // Add more points to create a "hard stop" in the color gradient. + PackedVector2Array points_x; + points_x.push_back(Point2(+extents, 0)); + points_x.push_back(Point2()); + points_x.push_back(Point2()); + points_x.push_back(Point2(-extents, 0)); + + PackedVector2Array points_y; + points_y.push_back(Point2(0, +extents)); + points_y.push_back(Point2()); + points_y.push_back(Point2()); + points_y.push_back(Point2(0, -extents)); + + // Use the axis color which is brighter for the positive axis. + // Use a darkened axis color for the negative axis. + // This makes it possible to see in which direction the Position3D node is rotated + // (which can be important depending on how it's used). + // Axis colors are taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`). + PackedColorArray colors_x; + const Color color_x = Color(0.96, 0.20, 0.32); + colors_x.push_back(color_x); + colors_x.push_back(color_x); + colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); + colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5)); + draw_multiline_colors(points_x, colors_x); + + PackedColorArray colors_y; + const Color color_y = Color(0.53, 0.84, 0.01); + colors_y.push_back(color_y); + colors_y.push_back(color_y); + colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); + colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5)); + draw_multiline_colors(points_y, colors_y); } #ifdef TOOLS_ENABLED diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 22180797f0..8f1f5fadbc 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -30,6 +30,69 @@ #include "skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#endif //TOOLS_ENABLED + +bool Bone2D::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("auto_calculate_length_and_angle")) { + set_autocalculate_length_and_angle(p_value); + } else if (path.begins_with("length")) { + set_length(p_value); + } else if (path.begins_with("bone_angle")) { + set_bone_angle(Math::deg2rad(float(p_value))); + } else if (path.begins_with("default_length")) { + set_length(p_value); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor_settings/show_bone_gizmo")) { + _editor_set_show_bone_gizmo(p_value); + } +#endif // TOOLS_ENABLED + + return true; +} + +bool Bone2D::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("auto_calculate_length_and_angle")) { + r_ret = get_autocalculate_length_and_angle(); + } else if (path.begins_with("length")) { + r_ret = get_length(); + } else if (path.begins_with("bone_angle")) { + r_ret = Math::rad2deg(get_bone_angle()); + } else if (path.begins_with("default_length")) { + r_ret = get_length(); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor_settings/show_bone_gizmo")) { + r_ret = _editor_get_show_bone_gizmo(); + } +#endif // TOOLS_ENABLED + + return true; +} + +void Bone2D::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::BOOL, "auto_calculate_length_and_angle", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (!autocalculate_length_and_angle) { + p_list->push_back(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "1, 1024, 1", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::FLOAT, "bone_angle", PROPERTY_HINT_RANGE, "-360, 360, 0.01", PROPERTY_USAGE_DEFAULT)); + } + +#ifdef TOOLS_ENABLED + p_list->push_back(PropertyInfo(Variant::BOOL, "editor_settings/show_bone_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); +#endif // TOOLS_ENABLED +} + void Bone2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { Node *parent = get_parent(); @@ -53,19 +116,54 @@ void Bone2D::_notification(int p_what) { skeleton->bones.push_back(bone); skeleton->_make_bone_setup_dirty(); } + + cache_transform = get_transform(); + copy_transform_to_cache = true; + +#ifdef TOOLS_ENABLED + // Only draw the gizmo in the editor! + if (Engine::get_singleton()->is_editor_hint() == false) { + return; + } + + update(); +#endif // TOOLS_ENABLED } - if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { + + else if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { if (skeleton) { skeleton->_make_transform_dirty(); } + if (copy_transform_to_cache) { + cache_transform = get_transform(); + } +#ifdef TOOLS_ENABLED + // Only draw the gizmo in the editor! + if (Engine::get_singleton()->is_editor_hint() == false) { + return; + } + + update(); + + if (get_parent()) { + Bone2D *parent_bone = Object::cast_to<Bone2D>(get_parent()); + if (parent_bone) { + parent_bone->update(); + } + } +#endif // TOOLS_ENABLED } - if (p_what == NOTIFICATION_MOVED_IN_PARENT) { + + else if (p_what == NOTIFICATION_MOVED_IN_PARENT) { if (skeleton) { skeleton->_make_bone_setup_dirty(); } + if (copy_transform_to_cache) { + cache_transform = get_transform(); + } } - if (p_what == NOTIFICATION_EXIT_TREE) { + else if (p_what == NOTIFICATION_EXIT_TREE) { if (skeleton) { for (int i = 0; i < skeleton->bones.size(); i++) { if (skeleton->bones[i].bone == this) { @@ -77,9 +175,200 @@ void Bone2D::_notification(int p_what) { skeleton = nullptr; } parent_bone = nullptr; + set_transform(cache_transform); } + + else if (p_what == NOTIFICATION_READY) { + if (autocalculate_length_and_angle) { + calculate_length_and_rotation(); + } + } +#ifdef TOOLS_ENABLED + else if (p_what == NOTIFICATION_EDITOR_PRE_SAVE || p_what == NOTIFICATION_EDITOR_POST_SAVE) { + Transform2D tmp_trans = get_transform(); + set_transform(cache_transform); + cache_transform = tmp_trans; + } + // Bone2D Editor gizmo drawing: +#ifndef _MSC_VER +#warning TODO Bone2D gizmo drawing needs to be moved to an editor plugin +#endif + else if (p_what == NOTIFICATION_DRAW) { + // Only draw the gizmo in the editor! + if (Engine::get_singleton()->is_editor_hint() == false) { + return; + } + + if (editor_gizmo_rid.is_null()) { + editor_gizmo_rid = RenderingServer::get_singleton()->canvas_item_create(); + RenderingServer::get_singleton()->canvas_item_set_parent(editor_gizmo_rid, get_canvas_item()); + RenderingServer::get_singleton()->canvas_item_set_z_as_relative_to_parent(editor_gizmo_rid, true); + RenderingServer::get_singleton()->canvas_item_set_z_index(editor_gizmo_rid, 10); + } + RenderingServer::get_singleton()->canvas_item_clear(editor_gizmo_rid); + + if (!_editor_show_bone_gizmo) { + return; + } + + // Undo scaling + Transform2D editor_gizmo_trans = Transform2D(); + editor_gizmo_trans.set_scale(Vector2(1, 1) / get_global_scale()); + RenderingServer::get_singleton()->canvas_item_set_transform(editor_gizmo_rid, editor_gizmo_trans); + + Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); + Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2"); + Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); + Color bone_outline_color = EditorSettings::get_singleton()->get("editors/2d/bone_outline_color"); + Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); + + bool Bone2D_found = false; + for (int i = 0; i < get_child_count(); i++) { + Bone2D *child_node = nullptr; + child_node = Object::cast_to<Bone2D>(get_child(i)); + if (!child_node) { + continue; + } + Bone2D_found = true; + + Vector<Vector2> bone_shape; + Vector<Vector2> bone_shape_outline; + + _editor_get_bone_shape(&bone_shape, &bone_shape_outline, child_node); + + Vector<Color> colors; + if (has_meta("_local_pose_override_enabled_")) { + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + } else { + colors.push_back(bone_color1); + colors.push_back(bone_color2); + colors.push_back(bone_color1); + colors.push_back(bone_color2); + } + + Vector<Color> outline_colors; + if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) { + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + } else { + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + } + + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors); + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors); + } + + if (!Bone2D_found) { + Vector<Vector2> bone_shape; + Vector<Vector2> bone_shape_outline; + + _editor_get_bone_shape(&bone_shape, &bone_shape_outline, nullptr); + + Vector<Color> colors; + if (has_meta("_local_pose_override_enabled_")) { + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + } else { + colors.push_back(bone_color1); + colors.push_back(bone_color2); + colors.push_back(bone_color1); + colors.push_back(bone_color2); + } + + Vector<Color> outline_colors; + if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) { + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + } else { + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + } + + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors); + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors); + } + } +#endif // TOOLS_ENALBED } +#ifdef TOOLS_ENABLED +bool Bone2D::_editor_get_bone_shape(Vector<Vector2> *p_shape, Vector<Vector2> *p_outline_shape, Bone2D *p_other_bone) { + int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); + int bone_outline_width = EditorSettings::get_singleton()->get("editors/2d/bone_outline_size"); + + if (!is_inside_tree()) { + return false; //may have been removed + } + if (!p_other_bone && length <= 0) { + return false; + } + + Vector2 rel; + if (p_other_bone) { + rel = (p_other_bone->get_global_transform().get_origin() - get_global_transform().get_origin()); + rel = rel.rotated(-get_global_rotation()); // Undo Bone2D node's rotation so its drawn correctly regardless of the node's rotation + } else { + float angle_to_use = get_rotation() + bone_angle; + rel = Vector2(cos(angle_to_use), sin(angle_to_use)) * (length * MIN(get_global_scale().x, get_global_scale().y)); + rel = rel.rotated(-get_rotation()); // Undo Bone2D node's rotation so its drawn correctly regardless of the node's rotation + } + + Vector2 relt = rel.rotated(Math_PI * 0.5).normalized() * bone_width; + Vector2 reln = rel.normalized(); + Vector2 reltn = relt.normalized(); + + if (p_shape) { + p_shape->clear(); + p_shape->push_back(Vector2(0, 0)); + p_shape->push_back(rel * 0.2 + relt); + p_shape->push_back(rel); + p_shape->push_back(rel * 0.2 - relt); + } + + if (p_outline_shape) { + p_outline_shape->clear(); + p_outline_shape->push_back((-reln - reltn) * bone_outline_width); + p_outline_shape->push_back((-reln + reltn) * bone_outline_width); + p_outline_shape->push_back(rel * 0.2 + relt + reltn * bone_outline_width); + p_outline_shape->push_back(rel + (reln + reltn) * bone_outline_width); + p_outline_shape->push_back(rel + (reln - reltn) * bone_outline_width); + p_outline_shape->push_back(rel * 0.2 - relt - reltn * bone_outline_width); + } + return true; +} + +void Bone2D::_editor_set_show_bone_gizmo(bool p_show_gizmo) { + _editor_show_bone_gizmo = p_show_gizmo; + update(); +} + +bool Bone2D::_editor_get_show_bone_gizmo() const { + return _editor_show_bone_gizmo; +} +#endif // TOOLS_ENABLED + void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest); ClassDB::bind_method(D_METHOD("get_rest"), &Bone2D::get_rest); @@ -90,8 +379,14 @@ void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_length", "default_length"), &Bone2D::set_default_length); ClassDB::bind_method(D_METHOD("get_default_length"), &Bone2D::get_default_length); + ClassDB::bind_method(D_METHOD("set_autocalculate_length_and_angle", "auto_calculate"), &Bone2D::set_autocalculate_length_and_angle); + ClassDB::bind_method(D_METHOD("get_autocalculate_length_and_angle"), &Bone2D::get_autocalculate_length_and_angle); + ClassDB::bind_method(D_METHOD("set_length", "length"), &Bone2D::set_length); + ClassDB::bind_method(D_METHOD("get_length"), &Bone2D::get_length); + ClassDB::bind_method(D_METHOD("set_bone_angle", "angle"), &Bone2D::set_bone_angle); + ClassDB::bind_method(D_METHOD("get_bone_angle"), &Bone2D::get_bone_angle); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "rest"), "set_rest", "get_rest"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_length", PROPERTY_HINT_RANGE, "1,1024,1"), "set_default_length", "get_default_length"); } void Bone2D::set_rest(const Transform2D &p_rest) { @@ -119,12 +414,14 @@ void Bone2D::apply_rest() { set_transform(rest); } -void Bone2D::set_default_length(real_t p_length) { - default_length = p_length; +void Bone2D::set_default_length(float p_length) { + WARN_DEPRECATED_MSG("set_default_length is deprecated. Please use set_length instead!"); + set_length(p_length); } -real_t Bone2D::get_default_length() const { - return default_length; +float Bone2D::get_default_length() const { + WARN_DEPRECATED_MSG("get_default_length is deprecated. Please use get_length instead!"); + return get_length(); } int Bone2D::get_index_in_skeleton() const { @@ -150,16 +447,121 @@ TypedArray<String> Bone2D::get_configuration_warnings() const { return warnings; } +void Bone2D::calculate_length_and_rotation() { + // if there is at least a single child Bone2D node, we can calculate + // the length and direction. We will always just use the first Bone2D for this. + bool calculated = false; + int child_count = get_child_count(); + if (child_count > 0) { + for (int i = 0; i < child_count; i++) { + Bone2D *child = Object::cast_to<Bone2D>(get_child(i)); + if (child) { + Vector2 child_local_pos = to_local(child->get_global_transform().get_origin()); + length = child_local_pos.length(); + bone_angle = Math::atan2(child_local_pos.normalized().y, child_local_pos.normalized().x); + calculated = true; + break; + } + } + } + if (calculated) { + return; // Finished! + } else { + WARN_PRINT("No Bone2D children of node " + get_name() + ". Cannot calculate bone length or angle reliably.\nUsing transform rotation for bone angle"); + bone_angle = get_transform().get_rotation(); + return; + } +} + +void Bone2D::set_autocalculate_length_and_angle(bool p_autocalculate) { + autocalculate_length_and_angle = p_autocalculate; + if (autocalculate_length_and_angle) { + calculate_length_and_rotation(); + } + notify_property_list_changed(); +} + +bool Bone2D::get_autocalculate_length_and_angle() const { + return autocalculate_length_and_angle; +} + +void Bone2D::set_length(float p_length) { + length = p_length; + +#ifdef TOOLS_ENABLED + update(); +#endif // TOOLS_ENABLED +} + +float Bone2D::get_length() const { + return length; +} + +void Bone2D::set_bone_angle(float p_angle) { + bone_angle = p_angle; + +#ifdef TOOLS_ENABLED + update(); +#endif // TOOLS_ENABLED +} + +float Bone2D::get_bone_angle() const { + return bone_angle; +} + Bone2D::Bone2D() { + skeleton = nullptr; + parent_bone = nullptr; + skeleton_index = -1; + length = 16; + bone_angle = 0; + autocalculate_length_and_angle = true; set_notify_local_transform(true); //this is a clever hack so the bone knows no rest has been set yet, allowing to show an error. for (int i = 0; i < 3; i++) { rest[i] = Vector2(0, 0); } + copy_transform_to_cache = true; +} + +Bone2D::~Bone2D() { +#ifdef TOOLS_ENABLED + if (!editor_gizmo_rid.is_null()) { + RenderingServer::get_singleton()->free(editor_gizmo_rid); + } +#endif // TOOLS_ENABLED } ////////////////////////////////////// +bool Skeleton2D::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("modification_stack")) { + set_modification_stack(p_value); + return true; + } + return true; +} + +bool Skeleton2D::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("modification_stack")) { + r_ret = get_modification_stack(); + return true; + } + return true; +} + +void Skeleton2D::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back( + PropertyInfo(Variant::OBJECT, "modification_stack", + PROPERTY_HINT_RESOURCE_TYPE, + "SkeletonModificationStack2D", + PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); +} + void Skeleton2D::_make_bone_setup_dirty() { if (bone_setup_dirty) { return; @@ -189,6 +591,8 @@ void Skeleton2D::_update_bone_setup() { } else { bones.write[i].parent_index = -1; } + + bones.write[i].local_pose_override = bones[i].bone->get_skeleton_rest(); } transform_dirty = true; @@ -257,19 +661,121 @@ void Skeleton2D::_notification(int p_what) { if (transform_dirty) { _update_transform(); } - request_ready(); } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { RS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform()); + } else if (p_what == NOTIFICATION_INTERNAL_PROCESS) { + if (modification_stack.is_valid()) { + execute_modifications(get_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_process); + } + } else if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { + if (modification_stack.is_valid()) { + execute_modifications(get_physics_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_physics_process); + } } +#ifdef TOOLS_ENABLED + else if (p_what == NOTIFICATION_DRAW) { + if (Engine::get_singleton()->is_editor_hint()) { + if (modification_stack.is_valid()) { + modification_stack->draw_editor_gizmos(); + } + } + } +#endif // TOOLS_ENABLED } RID Skeleton2D::get_skeleton() const { return skeleton; } +void Skeleton2D::set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, float p_amount, bool p_persistent) { + ERR_FAIL_INDEX_MSG(p_bone_idx, bones.size(), "Bone index is out of range!"); + bones.write[p_bone_idx].local_pose_override = p_override; + bones.write[p_bone_idx].local_pose_override_amount = p_amount; + bones.write[p_bone_idx].local_pose_override_persistent = p_persistent; +} + +Transform2D Skeleton2D::get_bone_local_pose_override(int p_bone_idx) { + ERR_FAIL_INDEX_V_MSG(p_bone_idx, bones.size(), Transform2D(), "Bone index is out of range!"); + return bones[p_bone_idx].local_pose_override; +} + +void Skeleton2D::set_modification_stack(Ref<SkeletonModificationStack2D> p_stack) { + if (modification_stack.is_valid()) { + modification_stack->is_setup = false; + modification_stack->set_skeleton(nullptr); + + set_process_internal(false); + set_physics_process_internal(false); + } + modification_stack = p_stack; + if (modification_stack.is_valid()) { + modification_stack->set_skeleton(this); + modification_stack->setup(); + + set_process_internal(true); + set_physics_process_internal(true); + +#ifdef TOOLS_ENABLED + modification_stack->set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED + } +} + +Ref<SkeletonModificationStack2D> Skeleton2D::get_modification_stack() const { + return modification_stack; +} + +void Skeleton2D::execute_modifications(float p_delta, int p_execution_mode) { + if (!modification_stack.is_valid()) { + return; + } + + // Do not cache the transform changes caused by the modifications! + for (int i = 0; i < bones.size(); i++) { + bones[i].bone->copy_transform_to_cache = false; + } + + if (modification_stack->skeleton != this) { + modification_stack->set_skeleton(this); + } + + modification_stack->execute(p_delta, p_execution_mode); + + // Only apply the local pose override on _process. Otherwise, just calculate the local_pose_override and reset the transform. + if (p_execution_mode == SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_process) { + for (int i = 0; i < bones.size(); i++) { + if (bones[i].local_pose_override_amount > 0) { + bones[i].bone->set_meta("_local_pose_override_enabled_", true); + + Transform2D final_trans = bones[i].bone->cache_transform; + final_trans = final_trans.interpolate_with(bones[i].local_pose_override, bones[i].local_pose_override_amount); + bones[i].bone->set_transform(final_trans); + bones[i].bone->propagate_call("force_update_transform"); + + if (bones[i].local_pose_override_persistent) { + bones.write[i].local_pose_override_amount = 0.0; + } + } else { + // TODO: see if there is a way to undo the override without having to resort to setting every bone's transform. + bones[i].bone->remove_meta("_local_pose_override_enabled_"); + bones[i].bone->set_transform(bones[i].bone->cache_transform); + } + } + } + + // Cache any future transform changes + for (int i = 0; i < bones.size(); i++) { + bones[i].bone->copy_transform_to_cache = true; + } + +#ifdef TOOLS_ENABLED + modification_stack->set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED +} + void Skeleton2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_bone_setup"), &Skeleton2D::_update_bone_setup); ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform); @@ -279,6 +785,13 @@ void Skeleton2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton); + ClassDB::bind_method(D_METHOD("set_modification_stack", "modification_stack"), &Skeleton2D::set_modification_stack); + ClassDB::bind_method(D_METHOD("get_modification_stack"), &Skeleton2D::get_modification_stack); + ClassDB::bind_method(D_METHOD("execute_modifications", "delta", "execution_mode"), &Skeleton2D::execute_modifications); + + ClassDB::bind_method(D_METHOD("set_bone_local_pose_override", "bone_idx", "override_pose", "strength", "persistent"), &Skeleton2D::set_bone_local_pose_override); + ClassDB::bind_method(D_METHOD("get_bone_local_pose_override", "bone_idx"), &Skeleton2D::get_bone_local_pose_override); + ADD_SIGNAL(MethodInfo("bone_setup_changed")); } diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index fd62b87bde..59bd711960 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -32,6 +32,7 @@ #define SKELETON_2D_H #include "scene/2d/node_2d.h" +#include "scene/resources/skeleton_modification_2d.h" class Skeleton2D; @@ -46,15 +47,32 @@ class Bone2D : public Node2D { Bone2D *parent_bone = nullptr; Skeleton2D *skeleton = nullptr; Transform2D rest; - real_t default_length = 16.0; + + bool autocalculate_length_and_angle = true; + float length = 16; + float bone_angle = 0; int skeleton_index = -1; + void calculate_length_and_rotation(); + +#ifdef TOOLS_ENABLED + RID editor_gizmo_rid; + bool _editor_get_bone_shape(Vector<Vector2> *p_shape, Vector<Vector2> *p_outline_shape, Bone2D *p_other_bone); + bool _editor_show_bone_gizmo = true; +#endif // TOOLS ENABLED + protected: void _notification(int p_what); static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; public: + Transform2D cache_transform; + bool copy_transform_to_cache = true; + void set_rest(const Transform2D &p_rest); Transform2D get_rest() const; void apply_rest(); @@ -65,11 +83,26 @@ public: void set_default_length(real_t p_length); real_t get_default_length() const; + void set_autocalculate_length_and_angle(bool p_autocalculate); + bool get_autocalculate_length_and_angle() const; + void set_length(float p_length); + float get_length() const; + void set_bone_angle(float p_angle); + float get_bone_angle() const; + int get_index_in_skeleton() const; +#ifdef TOOLS_ENABLED + void _editor_set_show_bone_gizmo(bool p_show_gizmo); + bool _editor_get_show_bone_gizmo() const; +#endif // TOOLS_ENABLED + Bone2D(); + ~Bone2D(); }; +class SkeletonModificationStack2D; + class Skeleton2D : public Node2D { GDCLASS(Skeleton2D, Node2D); @@ -86,6 +119,11 @@ class Skeleton2D : public Node2D { int parent_index = 0; Transform2D accum_transform; Transform2D rest_inverse; + + //Transform2D local_pose_cache; + Transform2D local_pose_override; + float local_pose_override_amount = 0; + bool local_pose_override_persistent = false; }; Vector<Bone> bones; @@ -100,15 +138,28 @@ class Skeleton2D : public Node2D { RID skeleton; + Ref<SkeletonModificationStack2D> modification_stack; + protected: void _notification(int p_what); static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; public: int get_bone_count() const; Bone2D *get_bone(int p_idx); RID get_skeleton() const; + + void set_bone_local_pose_override(int p_bone_idx, Transform2D p_override, float p_amount, bool p_persistent = true); + Transform2D get_bone_local_pose_override(int p_bone_idx); + + Ref<SkeletonModificationStack2D> get_modification_stack() const; + void set_modification_stack(Ref<SkeletonModificationStack2D> p_stack); + void execute_modifications(float p_delta, int p_execution_mode); + Skeleton2D(); ~Skeleton2D(); }; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 24b907fe6c..e79dfb019c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -334,6 +334,12 @@ TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() { return show_navigation; } +void TileMap::set_y_sort_enabled(bool p_enable) { + Node2D::set_y_sort_enabled(p_enable); + _recreate_quadrants(); + emit_signal("changed"); +} + void TileMap::update_dirty_quadrants() { if (!pending_update) { return; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index f02455a84b..3001e6b471 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -279,6 +279,7 @@ public: int get_effective_quadrant_size() const; void update_dirty_quadrants(); + virtual void set_y_sort_enabled(bool p_enable) override; Vector2 map_to_world(const Vector2i &p_pos) const; Vector2i world_to_map(const Vector2 &p_pos) const; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 8feb47f1cc..c85b2c85a4 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -176,7 +176,7 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { { RigidBody2D *rb2d = Object::cast_to<RigidBody2D>(p_node); - if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || rb2d->get_mode() == RigidBody2D::MODE_RIGID))) { + if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_DYNAMIC || rb2d->get_mode() == RigidBody2D::MODE_DYNAMIC_LOCKED))) { add = true; meta = rb2d->get_mode(); } diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp deleted file mode 100644 index 7e7bc27cc2..0000000000 --- a/scene/2d/y_sort.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* y_sort.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "y_sort.h" - -void YSort::set_sort_enabled(bool p_enabled) { - sort_enabled = p_enabled; - RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), sort_enabled); -} - -bool YSort::is_sort_enabled() const { - return sort_enabled; -} - -void YSort::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_sort_enabled", "enabled"), &YSort::set_sort_enabled); - ClassDB::bind_method(D_METHOD("is_sort_enabled"), &YSort::is_sort_enabled); - - ADD_GROUP("Sort", "sort_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sort_enabled"), "set_sort_enabled", "is_sort_enabled"); -} - -YSort::YSort() { - RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); -} diff --git a/scene/3d/SCsub b/scene/3d/SCsub index ce69e8aa19..40bdaee47d 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -4,6 +4,5 @@ Import("env") if env["disable_3d"]: env.add_source_files(env.scene_sources, "node_3d.cpp") - env.add_source_files(env.scene_sources, "skeleton_3d.cpp") else: env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 55b26bc9fb..cad4330c17 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -964,7 +964,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,Inverse Square,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater"), "set_unit_size", "get_unit_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 70c535bd89..8aec493602 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -98,7 +98,7 @@ private: AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE; float unit_db = 0.0; - float unit_size = 1.0; + float unit_size = 10.0; float max_db = 3.0; float pitch_scale = 1.0; bool autoplay = false; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 041da4f6ff..1c9418ae83 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -150,8 +150,8 @@ void Camera3D::_notification(int p_what) { } } -Transform Camera3D::get_camera_transform() const { - Transform tr = get_global_transform().orthonormalized(); +Transform3D Camera3D::get_camera_transform() const { + Transform3D tr = get_global_transform().orthonormalized(); tr.origin += tr.basis.get_axis(1) * v_offset; tr.origin += tr.basis.get_axis(0) * h_offset; return tr; @@ -318,7 +318,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const { }; bool Camera3D::is_position_behind(const Vector3 &p_pos) const { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); Vector3 eyedir = -t.basis.get_axis(2).normalized(); return eyedir.dot(p_pos - t.origin) < near; } @@ -337,7 +337,7 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { } Vector3 endpoints[8]; - cm.get_endpoints(Transform(), endpoints); + cm.get_endpoints(Transform3D(), endpoints); Vector<Vector3> points; points.push_back(Vector3()); @@ -686,8 +686,8 @@ ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() con return process_callback; } -Transform ClippedCamera3D::get_camera_transform() const { - Transform t = Camera3D::get_camera_transform(); +Transform3D ClippedCamera3D::get_camera_transform() const { + Transform3D t = Camera3D::get_camera_transform(); t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset; return t; } @@ -735,7 +735,7 @@ void ClippedCamera3D::_notification(int p_what) { } } - Transform xf = get_global_transform(); + Transform3D xf = get_global_transform(); xf.origin = ray_from; xf.orthonormalize(); diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index cea61e4db8..d9ebe78f1a 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -134,7 +134,7 @@ public: void set_near(float p_near); void set_frustum_offset(Vector2 p_offset); - virtual Transform get_camera_transform() const; + virtual Transform3D get_camera_transform() const; virtual Vector3 project_ray_normal(const Point2 &p_pos) const; virtual Vector3 project_ray_origin(const Point2 &p_pos) const; @@ -207,7 +207,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); - virtual Transform get_camera_transform() const override; + virtual Transform3D get_camera_transform() const override; public: void set_clip_to_areas(bool p_clip); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index cba769a8f8..a04667e53b 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -326,9 +326,9 @@ void CollisionObject3D::_bind_methods() { ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes); ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner); - BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); + BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "position"), PropertyInfo(Variant::VECTOR3, "normal"), PropertyInfo(Variant::INT, "shape_idx"))); - ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); + ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "position"), PropertyInfo(Variant::VECTOR3, "normal"), PropertyInfo(Variant::INT, "shape_idx"))); ADD_SIGNAL(MethodInfo("mouse_entered")); ADD_SIGNAL(MethodInfo("mouse_exited")); @@ -406,7 +406,7 @@ Array CollisionObject3D::_get_shape_owners() { return ret; } -void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform) { +void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transform3D &p_transform) { ERR_FAIL_COND(!shapes.has(p_owner)); ShapeData &sd = shapes[p_owner]; @@ -421,9 +421,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf _update_shape_data(p_owner); } - -Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { - ERR_FAIL_COND_V(!shapes.has(p_owner), Transform()); +Transform3D CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { + ERR_FAIL_COND_V(!shapes.has(p_owner), Transform3D()); return shapes[p_owner].xform; } diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 7ff3c5efde..50a9b4fcd0 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -46,7 +46,7 @@ class CollisionObject3D : public Node3D { struct ShapeData { Object *owner = nullptr; - Transform xform; + Transform3D xform; struct ShapeBase { RID debug_shape; Ref<Shape3D> shape; @@ -66,7 +66,7 @@ class CollisionObject3D : public Node3D { Set<uint32_t> debug_shapes_to_update; int debug_shapes_count = 0; - Transform debug_shape_old_transform; + Transform3D debug_shape_old_transform; void _update_pickable(); @@ -107,8 +107,8 @@ public: void get_shape_owners(List<uint32_t> *r_owners); Array _get_shape_owners(); - void shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform); - Transform shape_owner_get_transform(uint32_t p_owner) const; + void shape_owner_set_transform(uint32_t p_owner, const Transform3D &p_transform); + Transform3D shape_owner_get_transform(uint32_t p_owner) const; Object *shape_owner_get_owner(uint32_t p_owner) const; void shape_owner_set_disabled(uint32_t p_owner, bool p_disabled); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index ac715b22b2..8a4f8b639b 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -171,7 +171,7 @@ TypedArray<String> CollisionPolygon3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (polygon.is_empty()) { diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 70d9cebb83..be3fde8013 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -124,7 +124,7 @@ TypedArray<String> CollisionShape3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (!shape.is_valid()) { diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index aa29728c73..2301fef651 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -574,7 +574,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } } - Transform emission_xform; + Transform3D emission_xform; Basis velocity_xform; if (!local_coords) { emission_xform = get_global_transform(); @@ -693,7 +693,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.custom[0] = Math::deg2rad(base_angle); //angle p.custom[1] = 0.0; //phase p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) - p.transform = Transform(); + p.transform = Transform3D(); p.time = 0; p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); p.base_color = Color(1, 1, 1, 1); @@ -1030,7 +1030,7 @@ void CPUParticles3D::_update_particle_data_buffer() { for (int i = 0; i < pc; i++) { int idx = order ? order[i] : i; - Transform t = r[idx].transform; + Transform3D t = r[idx].transform; if (!local_coords) { t = inv_emission_transform * t; @@ -1139,7 +1139,7 @@ void CPUParticles3D::_notification(int p_what) { float *ptr = w; for (int i = 0; i < pc; i++) { - Transform t = inv_emission_transform * r[i].transform; + Transform3D t = inv_emission_transform * r[i].transform; if (r[i].active) { ptr[0] = t.basis.elements[0][0]; diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index c073c93c47..b35e659757 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -83,7 +83,7 @@ private: bool emitting = false; struct Particle { - Transform transform; + Transform3D transform; Color color; float custom[4] = {}; Vector3 velocity; @@ -141,7 +141,7 @@ private: int fixed_fps = 0; bool fractional_delta = true; - Transform inv_emission_transform; + Transform3D inv_emission_transform; SafeFlag can_update; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 83181064c3..d7f4bfeb4e 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -391,7 +391,7 @@ void GPUParticles3D::_validate_property(PropertyInfo &property) const { } } -void GPUParticles3D::emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { +void GPUParticles3D::emit_particle(const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { RS::get_singleton()->particles_emit(particles, p_transform, p_velocity, p_color, p_custom, p_emit_flags); } @@ -458,7 +458,7 @@ void GPUParticles3D::_notification(int p_what) { } void GPUParticles3D::_skinning_changed() { - Vector<Transform> xforms; + Vector<Transform3D> xforms; if (skin.is_valid()) { xforms.resize(skin->get_bind_count()); for (int i = 0; i < skin->get_bind_count(); i++) { diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 1b354b0d2a..7b21cf03f1 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -171,7 +171,7 @@ public: EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM }; - void emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); + void emit_particle(const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); AABB capture_aabb() const; GPUParticles3D(); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 2d59461ff0..322bc60fce 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -131,7 +131,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform(); if (p_aabb.intersects(xf.xform(aabb))) { PlotMesh pm; @@ -147,7 +147,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, if (s->is_visible_in_tree()) { Array meshes = p_at_node->call("get_meshes"); for (int i = 0; i < meshes.size(); i += 2) { - Transform mxf = meshes[i]; + Transform3D mxf = meshes[i]; Ref<Mesh> mesh = meshes[i + 1]; if (!mesh.is_valid()) { continue; @@ -155,7 +155,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); if (p_aabb.intersects(xf.xform(aabb))) { PlotMesh pm; @@ -598,14 +598,14 @@ void GPUParticlesCollisionHeightField::_notification(int p_what) { if (follow_camera_mode && get_viewport()) { Camera3D *cam = get_viewport()->get_camera(); if (cam) { - Transform xform = get_global_transform(); + Transform3D xform = get_global_transform(); Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized(); Vector3 z_axis = xform.basis.get_axis(Vector3::AXIS_Z).normalized(); float x_len = xform.basis.get_scale().x; float z_len = xform.basis.get_scale().z; Vector3 cam_pos = cam->get_global_transform().origin; - Transform new_xform = xform; + Transform3D new_xform = xform; while (x_axis.dot(cam_pos - new_xform.origin) > x_len) { new_xform.origin += x_axis * x_len; diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 81c33663f3..c55463378d 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -119,7 +119,7 @@ private: struct PlotMesh { Ref<Mesh> mesh; - Transform local_xform; + Transform3D local_xform; }; void _find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes); diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/lightmap_gi.cpp index ef648a126e..cc1177d541 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* baked_lightmap.cpp */ +/* lightmap_gi.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "baked_lightmap.h" +#include "lightmap_gi.h" #include "core/io/config_file.h" #include "core/io/resource_saver.h" @@ -40,7 +40,7 @@ #include "core/templates/sort_array.h" #include "lightmap_probe.h" -void BakedLightmapData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) { +void LightmapGIData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) { User user; user.path = p_path; user.uv_scale = p_uv_scale; @@ -49,35 +49,35 @@ void BakedLightmapData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale users.push_back(user); } -int BakedLightmapData::get_user_count() const { +int LightmapGIData::get_user_count() const { return users.size(); } -NodePath BakedLightmapData::get_user_path(int p_user) const { +NodePath LightmapGIData::get_user_path(int p_user) const { ERR_FAIL_INDEX_V(p_user, users.size(), NodePath()); return users[p_user].path; } -int32_t BakedLightmapData::get_user_sub_instance(int p_user) const { +int32_t LightmapGIData::get_user_sub_instance(int p_user) const { ERR_FAIL_INDEX_V(p_user, users.size(), -1); return users[p_user].sub_instance; } -Rect2 BakedLightmapData::get_user_lightmap_uv_scale(int p_user) const { +Rect2 LightmapGIData::get_user_lightmap_uv_scale(int p_user) const { ERR_FAIL_INDEX_V(p_user, users.size(), Rect2()); return users[p_user].uv_scale; } -int BakedLightmapData::get_user_lightmap_slice_index(int p_user) const { +int LightmapGIData::get_user_lightmap_slice_index(int p_user) const { ERR_FAIL_INDEX_V(p_user, users.size(), -1); return users[p_user].slice_index; } -void BakedLightmapData::clear_users() { +void LightmapGIData::clear_users() { users.clear(); } -void BakedLightmapData::_set_user_data(const Array &p_data) { +void LightmapGIData::_set_user_data(const Array &p_data) { ERR_FAIL_COND(p_data.size() <= 0); ERR_FAIL_COND((p_data.size() % 4) != 0); @@ -86,7 +86,7 @@ void BakedLightmapData::_set_user_data(const Array &p_data) { } } -Array BakedLightmapData::_get_user_data() const { +Array LightmapGIData::_get_user_data() const { Array ret; for (int i = 0; i < users.size(); i++) { ret.push_back(users[i].path); @@ -97,33 +97,33 @@ Array BakedLightmapData::_get_user_data() const { return ret; } -RID BakedLightmapData::get_rid() const { +RID LightmapGIData::get_rid() const { return lightmap; } -void BakedLightmapData::clear() { +void LightmapGIData::clear() { users.clear(); } -void BakedLightmapData::set_light_texture(const Ref<TextureLayered> &p_light_texture) { +void LightmapGIData::set_light_texture(const Ref<TextureLayered> &p_light_texture) { light_texture = p_light_texture; RS::get_singleton()->lightmap_set_textures(lightmap, light_texture.is_valid() ? light_texture->get_rid() : RID(), uses_spherical_harmonics); } -Ref<TextureLayered> BakedLightmapData::get_light_texture() const { +Ref<TextureLayered> LightmapGIData::get_light_texture() const { return light_texture; } -void BakedLightmapData::set_uses_spherical_harmonics(bool p_enable) { +void LightmapGIData::set_uses_spherical_harmonics(bool p_enable) { uses_spherical_harmonics = p_enable; RS::get_singleton()->lightmap_set_textures(lightmap, light_texture.is_valid() ? light_texture->get_rid() : RID(), uses_spherical_harmonics); } -bool BakedLightmapData::is_using_spherical_harmonics() const { +bool LightmapGIData::is_using_spherical_harmonics() const { return uses_spherical_harmonics; } -void BakedLightmapData::set_capture_data(const AABB &p_bounds, bool p_interior, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { +void LightmapGIData::set_capture_data(const AABB &p_bounds, bool p_interior, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { if (p_points.size()) { int pc = p_points.size(); ERR_FAIL_COND(pc * 9 != p_point_sh.size()); @@ -141,31 +141,31 @@ void BakedLightmapData::set_capture_data(const AABB &p_bounds, bool p_interior, bounds = p_bounds; } -PackedVector3Array BakedLightmapData::get_capture_points() const { +PackedVector3Array LightmapGIData::get_capture_points() const { return RS::get_singleton()->lightmap_get_probe_capture_points(lightmap); } -PackedColorArray BakedLightmapData::get_capture_sh() const { +PackedColorArray LightmapGIData::get_capture_sh() const { return RS::get_singleton()->lightmap_get_probe_capture_sh(lightmap); } -PackedInt32Array BakedLightmapData::get_capture_tetrahedra() const { +PackedInt32Array LightmapGIData::get_capture_tetrahedra() const { return RS::get_singleton()->lightmap_get_probe_capture_tetrahedra(lightmap); } -PackedInt32Array BakedLightmapData::get_capture_bsp_tree() const { +PackedInt32Array LightmapGIData::get_capture_bsp_tree() const { return RS::get_singleton()->lightmap_get_probe_capture_bsp_tree(lightmap); } -AABB BakedLightmapData::get_capture_bounds() const { +AABB LightmapGIData::get_capture_bounds() const { return bounds; } -bool BakedLightmapData::is_interior() const { +bool LightmapGIData::is_interior() const { return interior; } -void BakedLightmapData::_set_probe_data(const Dictionary &p_data) { +void LightmapGIData::_set_probe_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("bounds")); ERR_FAIL_COND(!p_data.has("points")); ERR_FAIL_COND(!p_data.has("tetrahedra")); @@ -175,7 +175,7 @@ void BakedLightmapData::_set_probe_data(const Dictionary &p_data) { set_capture_data(p_data["bounds"], p_data["interior"], p_data["points"], p_data["sh"], p_data["tetrahedra"], p_data["bsp"]); } -Dictionary BakedLightmapData::_get_probe_data() const { +Dictionary LightmapGIData::_get_probe_data() const { Dictionary d; d["bounds"] = get_capture_bounds(); d["points"] = get_capture_points(); @@ -186,23 +186,23 @@ Dictionary BakedLightmapData::_get_probe_data() const { return d; } -void BakedLightmapData::_bind_methods() { - ClassDB::bind_method(D_METHOD("_set_user_data", "data"), &BakedLightmapData::_set_user_data); - ClassDB::bind_method(D_METHOD("_get_user_data"), &BakedLightmapData::_get_user_data); +void LightmapGIData::_bind_methods() { + ClassDB::bind_method(D_METHOD("_set_user_data", "data"), &LightmapGIData::_set_user_data); + ClassDB::bind_method(D_METHOD("_get_user_data"), &LightmapGIData::_get_user_data); - ClassDB::bind_method(D_METHOD("set_light_texture", "light_texture"), &BakedLightmapData::set_light_texture); - ClassDB::bind_method(D_METHOD("get_light_texture"), &BakedLightmapData::get_light_texture); + ClassDB::bind_method(D_METHOD("set_light_texture", "light_texture"), &LightmapGIData::set_light_texture); + ClassDB::bind_method(D_METHOD("get_light_texture"), &LightmapGIData::get_light_texture); - ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &BakedLightmapData::set_uses_spherical_harmonics); - ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &BakedLightmapData::is_using_spherical_harmonics); + ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &LightmapGIData::set_uses_spherical_harmonics); + ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &LightmapGIData::is_using_spherical_harmonics); - ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &BakedLightmapData::add_user); - ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count); - ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path); - ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users); + ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &LightmapGIData::add_user); + ClassDB::bind_method(D_METHOD("get_user_count"), &LightmapGIData::get_user_count); + ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &LightmapGIData::get_user_path); + ClassDB::bind_method(D_METHOD("clear_users"), &LightmapGIData::clear_users); - ClassDB::bind_method(D_METHOD("_set_probe_data", "data"), &BakedLightmapData::_set_probe_data); - ClassDB::bind_method(D_METHOD("_get_probe_data"), &BakedLightmapData::_get_probe_data); + ClassDB::bind_method(D_METHOD("_set_probe_data", "data"), &LightmapGIData::_set_probe_data); + ClassDB::bind_method(D_METHOD("_get_probe_data"), &LightmapGIData::_get_probe_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_texture", PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered"), "set_light_texture", "get_light_texture"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uses_spherical_harmonics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_uses_spherical_harmonics", "is_using_spherical_harmonics"); @@ -210,17 +210,17 @@ void BakedLightmapData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "probe_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_probe_data", "_get_probe_data"); } -BakedLightmapData::BakedLightmapData() { +LightmapGIData::LightmapGIData() { lightmap = RS::get_singleton()->lightmap_create(); } -BakedLightmapData::~BakedLightmapData() { +LightmapGIData::~LightmapGIData() { RS::get_singleton()->free(lightmap); } /////////////////////////// -void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &meshes, Vector<LightsFound> &lights, Vector<Vector3> &probes) { +void LightmapGI::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &meshes, Vector<LightsFound> &lights, Vector<Vector3> &probes) { MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node); if (mi && mi->get_gi_mode() == GeometryInstance3D::GI_MODE_BAKED && mi->is_visible_in_tree()) { Ref<Mesh> mesh = mi->get_mesh(); @@ -273,7 +273,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> if (!mi && s) { Array bmeshes = p_at_node->call("get_bake_bmeshes"); if (bmeshes.size() && (bmeshes.size() & 1) == 0) { - Transform xf = get_global_transform().affine_inverse() * s->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * s->get_global_transform(); for (int i = 0; i < bmeshes.size(); i += 2) { Ref<Mesh> mesh = bmeshes[i]; if (!mesh.is_valid()) { @@ -282,7 +282,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> MeshesFound mf; - Transform mesh_xf = bmeshes[i + 1]; + Transform3D mesh_xf = bmeshes[i + 1]; mf.xform = xf * mesh_xf; mf.node_path = get_path_to(s); mf.subindex = i / 2; @@ -306,7 +306,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> LightmapProbe *probe = Object::cast_to<LightmapProbe>(p_at_node); if (probe) { - Transform xf = get_global_transform().affine_inverse() * probe->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * probe->get_global_transform(); probes.push_back(xf.origin); } @@ -320,7 +320,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> } } -int BakedLightmap::_bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const { +int LightmapGI::_bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const { int over = 0; int under = 0; int coplanar = 0; @@ -348,7 +348,7 @@ int BakedLightmap::_bsp_get_simplex_side(const Vector<Vector3> &p_points, const //#define DEBUG_BSP -int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const LocalVector<Plane> &p_planes, LocalVector<int32_t> &planes_tested, const LocalVector<BSPSimplex> &p_simplices, const LocalVector<int32_t> &p_simplex_indices, LocalVector<BSPNode> &bsp_nodes) { +int32_t LightmapGI::_compute_bsp_tree(const Vector<Vector3> &p_points, const LocalVector<Plane> &p_planes, LocalVector<int32_t> &planes_tested, const LocalVector<BSPSimplex> &p_simplices, const LocalVector<int32_t> &p_simplex_indices, LocalVector<BSPNode> &bsp_nodes) { //if we reach here, it means there is more than one simplex int32_t node_index = (int32_t)bsp_nodes.size(); bsp_nodes.push_back(BSPNode()); @@ -533,7 +533,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const return node_index; } -bool BakedLightmap::_lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh) { +bool LightmapGI::_lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh) { BakeStepUD *bsud = (BakeStepUD *)ud; bool ret = false; if (bsud->func) { @@ -542,7 +542,7 @@ bool BakedLightmap::_lightmap_bake_step_function(float p_completion, const Strin return ret; } -void BakedLightmap::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle) { +void LightmapGI::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle) { for (int i = 0; i < 8; i++) { Vector3i pos = p_cell->offset; uint32_t half_size = p_cell->size / 2; @@ -578,7 +578,7 @@ void BakedLightmap::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_ } } -void BakedLightmap::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool, Vector3iHash> &positions_used, const AABB &p_bounds) { +void LightmapGI::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool, Vector3iHash> &positions_used, const AABB &p_bounds) { for (int i = 0; i < 8; i++) { Vector3i pos = p_cell->offset; if (i & 1) { @@ -618,7 +618,7 @@ void BakedLightmap::_gen_new_positions_from_octree(const GenProbesOctree *p_cell } } -BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) { +LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) { if (p_image_data_path == "") { if (get_light_data().is_null()) { return BAKE_ERROR_NO_SAVE_PATH; @@ -887,7 +887,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d } for (int i = 0; i < lights_found.size(); i++) { Light3D *light = lights_found[i].light; - Transform xf = lights_found[i].xform; + Transform3D xf = lights_found[i].xform; if (Object::cast_to<DirectionalLight3D>(light)) { DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light); @@ -1011,10 +1011,10 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d /* POSTBAKE: Save Light Data */ - Ref<BakedLightmapData> data; + Ref<LightmapGIData> data; if (get_light_data().is_valid()) { data = get_light_data(); - set_light_data(Ref<BakedLightmapData>()); //clear + set_light_data(Ref<LightmapGIData>()); //clear data->clear(); } else { data.instance(); @@ -1183,7 +1183,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d return BAKE_ERROR_OK; } -void BakedLightmap::_notification(int p_what) { +void LightmapGI::_notification(int p_what) { if (p_what == NOTIFICATION_POST_ENTER_TREE) { if (light_data.is_valid()) { _assign_lightmaps(); @@ -1197,7 +1197,7 @@ void BakedLightmap::_notification(int p_what) { } } -void BakedLightmap::_assign_lightmaps() { +void LightmapGI::_assign_lightmaps() { ERR_FAIL_COND(!light_data.is_valid()); for (int i = 0; i < light_data->get_user_count(); i++) { @@ -1216,7 +1216,7 @@ void BakedLightmap::_assign_lightmaps() { } } -void BakedLightmap::_clear_lightmaps() { +void LightmapGI::_clear_lightmaps() { ERR_FAIL_COND(!light_data.is_valid()); for (int i = 0; i < light_data->get_user_count(); i++) { Node *node = get_node(light_data->get_user_path(i)); @@ -1234,7 +1234,7 @@ void BakedLightmap::_clear_lightmaps() { } } -void BakedLightmap::set_light_data(const Ref<BakedLightmapData> &p_data) { +void LightmapGI::set_light_data(const Ref<LightmapGIData> &p_data) { if (light_data.is_valid()) { if (is_inside_tree()) { _clear_lightmaps(); @@ -1253,119 +1253,119 @@ void BakedLightmap::set_light_data(const Ref<BakedLightmapData> &p_data) { update_gizmo(); } -Ref<BakedLightmapData> BakedLightmap::get_light_data() const { +Ref<LightmapGIData> LightmapGI::get_light_data() const { return light_data; } -void BakedLightmap::set_bake_quality(BakeQuality p_quality) { +void LightmapGI::set_bake_quality(BakeQuality p_quality) { bake_quality = p_quality; } -BakedLightmap::BakeQuality BakedLightmap::get_bake_quality() const { +LightmapGI::BakeQuality LightmapGI::get_bake_quality() const { return bake_quality; } -AABB BakedLightmap::get_aabb() const { +AABB LightmapGI::get_aabb() const { return AABB(); } -Vector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> LightmapGI::get_faces(uint32_t p_usage_flags) const { return Vector<Face3>(); } -void BakedLightmap::set_use_denoiser(bool p_enable) { +void LightmapGI::set_use_denoiser(bool p_enable) { use_denoiser = p_enable; } -bool BakedLightmap::is_using_denoiser() const { +bool LightmapGI::is_using_denoiser() const { return use_denoiser; } -void BakedLightmap::set_directional(bool p_enable) { +void LightmapGI::set_directional(bool p_enable) { directional = p_enable; } -bool BakedLightmap::is_directional() const { +bool LightmapGI::is_directional() const { return directional; } -void BakedLightmap::set_interior(bool p_enable) { +void LightmapGI::set_interior(bool p_enable) { interior = p_enable; } -bool BakedLightmap::is_interior() const { +bool LightmapGI::is_interior() const { return interior; } -void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) { +void LightmapGI::set_environment_mode(EnvironmentMode p_mode) { environment_mode = p_mode; notify_property_list_changed(); } -BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const { +LightmapGI::EnvironmentMode LightmapGI::get_environment_mode() const { return environment_mode; } -void BakedLightmap::set_environment_custom_sky(const Ref<Sky> &p_sky) { +void LightmapGI::set_environment_custom_sky(const Ref<Sky> &p_sky) { environment_custom_sky = p_sky; } -Ref<Sky> BakedLightmap::get_environment_custom_sky() const { +Ref<Sky> LightmapGI::get_environment_custom_sky() const { return environment_custom_sky; } -void BakedLightmap::set_environment_custom_color(const Color &p_color) { +void LightmapGI::set_environment_custom_color(const Color &p_color) { environment_custom_color = p_color; } -Color BakedLightmap::get_environment_custom_color() const { +Color LightmapGI::get_environment_custom_color() const { return environment_custom_color; } -void BakedLightmap::set_environment_custom_energy(float p_energy) { +void LightmapGI::set_environment_custom_energy(float p_energy) { environment_custom_energy = p_energy; } -float BakedLightmap::get_environment_custom_energy() const { +float LightmapGI::get_environment_custom_energy() const { return environment_custom_energy; } -void BakedLightmap::set_bounces(int p_bounces) { +void LightmapGI::set_bounces(int p_bounces) { ERR_FAIL_COND(p_bounces < 0 || p_bounces > 16); bounces = p_bounces; } -int BakedLightmap::get_bounces() const { +int LightmapGI::get_bounces() const { return bounces; } -void BakedLightmap::set_bias(float p_bias) { +void LightmapGI::set_bias(float p_bias) { ERR_FAIL_COND(p_bias < 0.00001); bias = p_bias; } -float BakedLightmap::get_bias() const { +float LightmapGI::get_bias() const { return bias; } -void BakedLightmap::set_max_texture_size(int p_size) { +void LightmapGI::set_max_texture_size(int p_size) { ERR_FAIL_COND(p_size < 2048); max_texture_size = p_size; } -int BakedLightmap::get_max_texture_size() const { +int LightmapGI::get_max_texture_size() const { return max_texture_size; } -void BakedLightmap::set_generate_probes(GenerateProbes p_generate_probes) { +void LightmapGI::set_generate_probes(GenerateProbes p_generate_probes) { gen_probes = p_generate_probes; } -BakedLightmap::GenerateProbes BakedLightmap::get_generate_probes() const { +LightmapGI::GenerateProbes LightmapGI::get_generate_probes() const { return gen_probes; } -void BakedLightmap::_validate_property(PropertyInfo &property) const { +void LightmapGI::_validate_property(PropertyInfo &property) const { if (property.name == "environment_custom_sky" && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) { property.usage = 0; } @@ -1377,47 +1377,47 @@ void BakedLightmap::_validate_property(PropertyInfo &property) const { } } -void BakedLightmap::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_light_data", "data"), &BakedLightmap::set_light_data); - ClassDB::bind_method(D_METHOD("get_light_data"), &BakedLightmap::get_light_data); +void LightmapGI::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_light_data", "data"), &LightmapGI::set_light_data); + ClassDB::bind_method(D_METHOD("get_light_data"), &LightmapGI::get_light_data); - ClassDB::bind_method(D_METHOD("set_bake_quality", "bake_quality"), &BakedLightmap::set_bake_quality); - ClassDB::bind_method(D_METHOD("get_bake_quality"), &BakedLightmap::get_bake_quality); + ClassDB::bind_method(D_METHOD("set_bake_quality", "bake_quality"), &LightmapGI::set_bake_quality); + ClassDB::bind_method(D_METHOD("get_bake_quality"), &LightmapGI::get_bake_quality); - ClassDB::bind_method(D_METHOD("set_bounces", "bounces"), &BakedLightmap::set_bounces); - ClassDB::bind_method(D_METHOD("get_bounces"), &BakedLightmap::get_bounces); + ClassDB::bind_method(D_METHOD("set_bounces", "bounces"), &LightmapGI::set_bounces); + ClassDB::bind_method(D_METHOD("get_bounces"), &LightmapGI::get_bounces); - ClassDB::bind_method(D_METHOD("set_generate_probes", "subdivision"), &BakedLightmap::set_generate_probes); - ClassDB::bind_method(D_METHOD("get_generate_probes"), &BakedLightmap::get_generate_probes); + ClassDB::bind_method(D_METHOD("set_generate_probes", "subdivision"), &LightmapGI::set_generate_probes); + ClassDB::bind_method(D_METHOD("get_generate_probes"), &LightmapGI::get_generate_probes); - ClassDB::bind_method(D_METHOD("set_bias", "bias"), &BakedLightmap::set_bias); - ClassDB::bind_method(D_METHOD("get_bias"), &BakedLightmap::get_bias); + ClassDB::bind_method(D_METHOD("set_bias", "bias"), &LightmapGI::set_bias); + ClassDB::bind_method(D_METHOD("get_bias"), &LightmapGI::get_bias); - ClassDB::bind_method(D_METHOD("set_environment_mode", "mode"), &BakedLightmap::set_environment_mode); - ClassDB::bind_method(D_METHOD("get_environment_mode"), &BakedLightmap::get_environment_mode); + ClassDB::bind_method(D_METHOD("set_environment_mode", "mode"), &LightmapGI::set_environment_mode); + ClassDB::bind_method(D_METHOD("get_environment_mode"), &LightmapGI::get_environment_mode); - ClassDB::bind_method(D_METHOD("set_environment_custom_sky", "sky"), &BakedLightmap::set_environment_custom_sky); - ClassDB::bind_method(D_METHOD("get_environment_custom_sky"), &BakedLightmap::get_environment_custom_sky); + ClassDB::bind_method(D_METHOD("set_environment_custom_sky", "sky"), &LightmapGI::set_environment_custom_sky); + ClassDB::bind_method(D_METHOD("get_environment_custom_sky"), &LightmapGI::get_environment_custom_sky); - ClassDB::bind_method(D_METHOD("set_environment_custom_color", "color"), &BakedLightmap::set_environment_custom_color); - ClassDB::bind_method(D_METHOD("get_environment_custom_color"), &BakedLightmap::get_environment_custom_color); + ClassDB::bind_method(D_METHOD("set_environment_custom_color", "color"), &LightmapGI::set_environment_custom_color); + ClassDB::bind_method(D_METHOD("get_environment_custom_color"), &LightmapGI::get_environment_custom_color); - ClassDB::bind_method(D_METHOD("set_environment_custom_energy", "energy"), &BakedLightmap::set_environment_custom_energy); - ClassDB::bind_method(D_METHOD("get_environment_custom_energy"), &BakedLightmap::get_environment_custom_energy); + ClassDB::bind_method(D_METHOD("set_environment_custom_energy", "energy"), &LightmapGI::set_environment_custom_energy); + ClassDB::bind_method(D_METHOD("get_environment_custom_energy"), &LightmapGI::get_environment_custom_energy); - ClassDB::bind_method(D_METHOD("set_max_texture_size", "max_texture_size"), &BakedLightmap::set_max_texture_size); - ClassDB::bind_method(D_METHOD("get_max_texture_size"), &BakedLightmap::get_max_texture_size); + ClassDB::bind_method(D_METHOD("set_max_texture_size", "max_texture_size"), &LightmapGI::set_max_texture_size); + ClassDB::bind_method(D_METHOD("get_max_texture_size"), &LightmapGI::get_max_texture_size); - ClassDB::bind_method(D_METHOD("set_use_denoiser", "use_denoiser"), &BakedLightmap::set_use_denoiser); - ClassDB::bind_method(D_METHOD("is_using_denoiser"), &BakedLightmap::is_using_denoiser); + ClassDB::bind_method(D_METHOD("set_use_denoiser", "use_denoiser"), &LightmapGI::set_use_denoiser); + ClassDB::bind_method(D_METHOD("is_using_denoiser"), &LightmapGI::is_using_denoiser); - ClassDB::bind_method(D_METHOD("set_interior", "enable"), &BakedLightmap::set_interior); - ClassDB::bind_method(D_METHOD("is_interior"), &BakedLightmap::is_interior); + ClassDB::bind_method(D_METHOD("set_interior", "enable"), &LightmapGI::set_interior); + ClassDB::bind_method(D_METHOD("is_interior"), &LightmapGI::is_interior); - ClassDB::bind_method(D_METHOD("set_directional", "directional"), &BakedLightmap::set_directional); - ClassDB::bind_method(D_METHOD("is_directional"), &BakedLightmap::is_directional); + ClassDB::bind_method(D_METHOD("set_directional", "directional"), &LightmapGI::set_directional); + ClassDB::bind_method(D_METHOD("is_directional"), &LightmapGI::is_directional); - // ClassDB::bind_method(D_METHOD("bake", "from_node"), &BakedLightmap::bake, DEFVAL(Variant())); + // ClassDB::bind_method(D_METHOD("bake", "from_node"), &LightmapGI::bake, DEFVAL(Variant())); ADD_GROUP("Tweaks", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra"), "set_bake_quality", "get_bake_quality"); @@ -1435,7 +1435,7 @@ void BakedLightmap::_bind_methods() { ADD_GROUP("Gen Probes", "generate_probes_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "generate_probes_subdiv", PROPERTY_HINT_ENUM, "Disabled,4,8,16,32"), "set_generate_probes", "get_generate_probes"); ADD_GROUP("Data", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_data", PROPERTY_HINT_RESOURCE_TYPE, "BakedLightmapData"), "set_light_data", "get_light_data"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_data", PROPERTY_HINT_RESOURCE_TYPE, "LightmapGIData"), "set_light_data", "get_light_data"); BIND_ENUM_CONSTANT(BAKE_QUALITY_LOW); BIND_ENUM_CONSTANT(BAKE_QUALITY_MEDIUM); @@ -1462,5 +1462,5 @@ void BakedLightmap::_bind_methods() { BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_CUSTOM_COLOR); } -BakedLightmap::BakedLightmap() { +LightmapGI::LightmapGI() { } diff --git a/scene/3d/baked_lightmap.h b/scene/3d/lightmap_gi.h index e2d89ab2d0..8a54512383 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/lightmap_gi.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* baked_lightmap.h */ +/* lightmap_gi.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BAKED_LIGHTMAP_H -#define BAKED_LIGHTMAP_H +#ifndef LIGHTMAP_GI_H +#define LIGHTMAP_GI_H #include "core/templates/local_vector.h" #include "scene/3d/light_3d.h" @@ -39,8 +39,8 @@ #include "scene/3d/visual_instance_3d.h" #include "scene/resources/sky.h" -class BakedLightmapData : public Resource { - GDCLASS(BakedLightmapData, Resource); +class LightmapGIData : public Resource { + GDCLASS(LightmapGIData, Resource); RES_BASE_EXTENSION("lmbake") Ref<TextureLayered> light_texture; @@ -95,12 +95,12 @@ public: void clear(); virtual RID get_rid() const override; - BakedLightmapData(); - ~BakedLightmapData(); + LightmapGIData(); + ~LightmapGIData(); }; -class BakedLightmap : public VisualInstance3D { - GDCLASS(BakedLightmap, VisualInstance3D); +class LightmapGI : public VisualInstance3D { + GDCLASS(LightmapGI, VisualInstance3D); public: enum BakeQuality { @@ -149,15 +149,15 @@ private: bool directional = false; GenerateProbes gen_probes = GENERATE_PROBES_DISABLED; - Ref<BakedLightmapData> light_data; + Ref<LightmapGIData> light_data; struct LightsFound { - Transform xform; + Transform3D xform; Light3D *light = nullptr; }; struct MeshesFound { - Transform xform; + Transform3D xform; NodePath node_path; int32_t subindex = 0; Ref<Mesh> mesh; @@ -230,8 +230,8 @@ protected: void _notification(int p_what); public: - void set_light_data(const Ref<BakedLightmapData> &p_data); - Ref<BakedLightmapData> get_light_data() const; + void set_light_data(const Ref<LightmapGIData> &p_data); + Ref<LightmapGIData> get_light_data() const; void set_bake_quality(BakeQuality p_quality); BakeQuality get_bake_quality() const; @@ -273,12 +273,12 @@ public: Vector<Face3> get_faces(uint32_t p_usage_flags) const override; BakeError bake(Node *p_from_node, String p_image_data_path = "", Lightmapper::BakeStepFunc p_bake_step = nullptr, void *p_bake_userdata = nullptr); - BakedLightmap(); + LightmapGI(); }; -VARIANT_ENUM_CAST(BakedLightmap::BakeQuality); -VARIANT_ENUM_CAST(BakedLightmap::GenerateProbes); -VARIANT_ENUM_CAST(BakedLightmap::BakeError); -VARIANT_ENUM_CAST(BakedLightmap::EnvironmentMode); +VARIANT_ENUM_CAST(LightmapGI::BakeQuality); +VARIANT_ENUM_CAST(LightmapGI::GenerateProbes); +VARIANT_ENUM_CAST(LightmapGI::BakeError); +VARIANT_ENUM_CAST(LightmapGI::EnvironmentMode); #endif // BAKED_LIGHTMAP_H diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 9842f152d7..636be083ab 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -105,7 +105,7 @@ void Listener3D::_notification(int p_what) { } } -Transform Listener3D::get_listener_transform() const { +Transform3D Listener3D::get_listener_transform() const { return get_global_transform().orthonormalized(); } diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h index 85657a8e53..bcc66f167c 100644 --- a/scene/3d/listener_3d.h +++ b/scene/3d/listener_3d.h @@ -65,7 +65,7 @@ public: void clear_current(); bool is_current() const; - virtual Transform get_listener_transform() const; + virtual Transform3D get_listener_transform() const; void set_visible_layers(uint32_t p_layers); uint32_t get_visible_layers() const; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index ba0f8cc870..e96e4df55c 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -223,7 +223,7 @@ void Node3D::_notification(int p_what) { } } -void Node3D::set_transform(const Transform &p_transform) { +void Node3D::set_transform(const Transform3D &p_transform) { data.local_transform = p_transform; data.dirty |= DIRTY_VECTORS; _propagate_transform_changed(this); @@ -232,8 +232,8 @@ void Node3D::set_transform(const Transform &p_transform) { } } -void Node3D::set_global_transform(const Transform &p_transform) { - Transform xform = +void Node3D::set_global_transform(const Transform3D &p_transform) { + Transform3D xform = (data.parent && !data.top_level_active) ? data.parent->get_global_transform().affine_inverse() * p_transform : p_transform; @@ -241,16 +241,15 @@ void Node3D::set_global_transform(const Transform &p_transform) { set_transform(xform); } -Transform Node3D::get_transform() const { +Transform3D Node3D::get_transform() const { if (data.dirty & DIRTY_LOCAL) { _update_local_transform(); } return data.local_transform; } - -Transform Node3D::get_global_transform() const { - ERR_FAIL_COND_V(!is_inside_tree(), Transform()); +Transform3D Node3D::get_global_transform() const { + ERR_FAIL_COND_V(!is_inside_tree(), Transform3D()); if (data.dirty & DIRTY_GLOBAL) { if (data.dirty & DIRTY_LOCAL) { @@ -274,11 +273,11 @@ Transform Node3D::get_global_transform() const { } #ifdef TOOLS_ENABLED -Transform Node3D::get_global_gizmo_transform() const { +Transform3D Node3D::get_global_gizmo_transform() const { return get_global_transform(); } -Transform Node3D::get_local_gizmo_transform() const { +Transform3D Node3D::get_local_gizmo_transform() const { return get_transform(); } #endif @@ -287,12 +286,11 @@ Node3D *Node3D::get_parent_spatial() const { return data.parent; } -Transform Node3D::get_relative_transform(const Node *p_parent) const { - if (p_parent == this) { - return Transform(); - } +Transform3D Node3D::get_relative_transform(const Node *p_parent) const { + if (p_parent == this) + return Transform3D(); - ERR_FAIL_COND_V(!data.parent, Transform()); + ERR_FAIL_COND_V(!data.parent, Transform3D()); if (p_parent == data.parent) { return get_transform(); @@ -301,8 +299,8 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const { } } -void Node3D::set_translation(const Vector3 &p_translation) { - data.local_transform.origin = p_translation; +void Node3D::set_position(const Vector3 &p_position) { + data.local_transform.origin = p_position; _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -341,7 +339,7 @@ void Node3D::set_scale(const Vector3 &p_scale) { } } -Vector3 Node3D::get_translation() const { +Vector3 Node3D::get_position() const { return data.local_transform.origin; } @@ -557,87 +555,87 @@ bool Node3D::is_visible() const { } void Node3D::rotate_object_local(const Vector3 &p_axis, float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate_local(p_axis, p_angle); set_transform(t); } void Node3D::rotate(const Vector3 &p_axis, float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(p_axis, p_angle); set_transform(t); } void Node3D::rotate_x(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(1, 0, 0), p_angle); set_transform(t); } void Node3D::rotate_y(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 1, 0), p_angle); set_transform(t); } void Node3D::rotate_z(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 0, 1), p_angle); set_transform(t); } void Node3D::translate(const Vector3 &p_offset) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.translate(p_offset); set_transform(t); } void Node3D::translate_object_local(const Vector3 &p_offset) { - Transform t = get_transform(); + Transform3D t = get_transform(); - Transform s; + Transform3D s; s.translate(p_offset); set_transform(t * s); } void Node3D::scale(const Vector3 &p_ratio) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.scale(p_ratio); set_transform(t); } void Node3D::scale_object_local(const Vector3 &p_scale) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.scale_local(p_scale); set_transform(t); } void Node3D::global_rotate(const Vector3 &p_axis, float p_angle) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.basis.rotate(p_axis, p_angle); set_global_transform(t); } void Node3D::global_scale(const Vector3 &p_scale) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.basis.scale(p_scale); set_global_transform(t); } void Node3D::global_translate(const Vector3 &p_offset) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.origin += p_offset; set_global_transform(t); } void Node3D::orthonormalize() { - Transform t = get_transform(); + Transform3D t = get_transform(); t.orthonormalize(); set_transform(t); } void Node3D::set_identity() { - set_transform(Transform()); + set_transform(Transform3D()); } void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) { @@ -649,7 +647,7 @@ void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed."); ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed."); - Transform lookat; + Transform3D lookat; lookat.origin = p_pos; Vector3 original_scale(get_scale()); @@ -695,8 +693,8 @@ void Node3D::force_update_transform() { void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform); ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform); - ClassDB::bind_method(D_METHOD("set_translation", "translation"), &Node3D::set_translation); - ClassDB::bind_method(D_METHOD("get_translation"), &Node3D::get_translation); + ClassDB::bind_method(D_METHOD("set_position", "position"), &Node3D::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &Node3D::get_position); ClassDB::bind_method(D_METHOD("set_rotation", "euler"), &Node3D::set_rotation); ClassDB::bind_method(D_METHOD("get_rotation"), &Node3D::get_rotation); ClassDB::bind_method(D_METHOD("set_rotation_degrees", "euler_degrees"), &Node3D::set_rotation_degrees); @@ -758,16 +756,16 @@ void Node3D::_bind_methods() { BIND_CONSTANT(NOTIFICATION_EXIT_WORLD); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); - //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; + //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; ADD_GROUP("Transform", ""); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level"); ADD_GROUP("Matrix", ""); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); ADD_GROUP("Visibility", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", 0), "set_gizmo", "get_gizmo"); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index a62c7b31a8..09a96bf8ca 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -62,8 +62,8 @@ class Node3D : public Node { mutable SelfList<Node> xform_change; struct Data { - mutable Transform global_transform; - mutable Transform local_transform; + mutable Transform3D global_transform; + mutable Transform3D local_transform; mutable Vector3 rotation; mutable Vector3 scale = Vector3(1, 1, 1); @@ -122,25 +122,25 @@ public: Ref<World3D> get_world_3d() const; - void set_translation(const Vector3 &p_translation); + void set_position(const Vector3 &p_position); void set_rotation(const Vector3 &p_euler_rad); void set_rotation_degrees(const Vector3 &p_euler_deg); void set_scale(const Vector3 &p_scale); - Vector3 get_translation() const; + Vector3 get_position() const; Vector3 get_rotation() const; Vector3 get_rotation_degrees() const; Vector3 get_scale() const; - void set_transform(const Transform &p_transform); - void set_global_transform(const Transform &p_transform); + void set_transform(const Transform3D &p_transform); + void set_global_transform(const Transform3D &p_transform); - Transform get_transform() const; - Transform get_global_transform() const; + Transform3D get_transform() const; + Transform3D get_global_transform() const; #ifdef TOOLS_ENABLED - virtual Transform get_global_gizmo_transform() const; - virtual Transform get_local_gizmo_transform() const; + virtual Transform3D get_global_gizmo_transform() const; + virtual Transform3D get_local_gizmo_transform() const; #endif void set_as_top_level(bool p_enabled); @@ -156,7 +156,7 @@ public: _FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; } - Transform get_relative_transform(const Node *p_parent) const; + Transform3D get_relative_transform(const Node *p_parent) const; void rotate(const Vector3 &p_axis, float p_angle); void rotate_x(float p_angle); diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index d3a256db34..429e1d4b98 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -233,7 +233,7 @@ void OccluderInstance3D::_bake_node(Node *p_node, PackedVector3Array &r_vertices } if (valid) { - Transform global_to_local = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D global_to_local = get_global_transform().affine_inverse() * mi->get_global_transform(); for (int i = 0; i < mesh->get_surface_count(); i++) { if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 4ec4ee6207..de115b35e3 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -108,7 +108,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { } Vector3 pos = c->interpolate_baked(offset, cubic); - Transform t = get_transform(); + Transform3D t = get_transform(); // Vector3 pos_offset = Vector3(h_offset, v_offset, 0); not used in all cases // will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formerly used diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index e895d18604..25c7c3d798 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -43,16 +43,35 @@ #include "editor/plugins/node_3d_editor_plugin.h" #endif -Vector3 PhysicsBody3D::get_linear_velocity() const { - return Vector3(); +void PhysicsBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.001)); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody3D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.001)); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicsBody3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicsBody3D::get_axis_lock); + + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); + ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); + ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); } -Vector3 PhysicsBody3D::get_angular_velocity() const { - return Vector3(); +PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : + CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); } -real_t PhysicsBody3D::get_inverse_mass() const { - return 0; +PhysicsBody3D::~PhysicsBody3D() { + if (motion_cache.is_valid()) { + motion_cache->owner = nullptr; + } } TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { @@ -83,11 +102,75 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) { PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid()); } -void PhysicsBody3D::_bind_methods() {} +Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) { + PhysicsServer3D::MotionResult result; + if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; + } + + motion_cache->result = result; -PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : - CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); + return motion_cache; + } + + return Ref<KinematicCollision3D>(); +} + +bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) { + Transform3D gt = get_global_transform(); + bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes); + + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + r_result.motion[i] = 0; + } + } + + if (!p_test_only) { + gt.origin += r_result.motion; + set_global_transform(gt); + } + + return colliding; +} + +bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision3D> &r_collision, real_t p_margin) { + ERR_FAIL_COND_V(!is_inside_tree(), false); + + PhysicsServer3D::MotionResult *r = nullptr; + if (r_collision.is_valid()) { + // Needs const_cast because method bindings don't support non-const Ref. + r = const_cast<PhysicsServer3D::MotionResult *>(&r_collision->result); + } + + return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes); +} + +void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + if (p_lock) { + locked_axis |= p_axis; + } else { + locked_axis &= (~p_axis); + } + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicsBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return (locked_axis & p_axis); +} + +Vector3 PhysicsBody3D::get_linear_velocity() const { + return Vector3(); +} + +Vector3 PhysicsBody3D::get_angular_velocity() const { + return Vector3(); +} + +real_t PhysicsBody3D::get_inverse_mass() const { + return 0; } void StaticBody3D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { @@ -109,14 +192,44 @@ Ref<PhysicsMaterial> StaticBody3D::get_physics_material_override() const { return physics_material_override; } +void StaticBody3D::set_kinematic_motion_enabled(bool p_enabled) { + if (p_enabled == kinematic_motion) { + return; + } + + kinematic_motion = p_enabled; + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC); + } else { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); + } + + _update_kinematic_motion(); +} + +bool StaticBody3D::is_kinematic_motion_enabled() const { + return kinematic_motion; +} + void StaticBody3D::set_constant_linear_velocity(const Vector3 &p_vel) { constant_linear_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + } } void StaticBody3D::set_constant_angular_velocity(const Vector3 &p_vel) { constant_angular_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + } } Vector3 StaticBody3D::get_constant_linear_velocity() const { @@ -127,30 +240,81 @@ Vector3 StaticBody3D::get_constant_angular_velocity() const { return constant_angular_velocity; } +Vector3 StaticBody3D::get_linear_velocity() const { + return linear_velocity; +} + +Vector3 StaticBody3D::get_angular_velocity() const { + return angular_velocity; +} + +void StaticBody3D::_notification(int p_what) { + if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + ERR_FAIL_COND(!kinematic_motion); + + real_t delta_time = get_physics_process_delta_time(); + + Transform3D new_transform = get_global_transform(); + new_transform.origin += constant_linear_velocity * delta_time; + + real_t ang_vel = constant_angular_velocity.length(); + if (!Math::is_zero_approx(ang_vel)) { + Vector3 ang_vel_axis = constant_angular_velocity / ang_vel; + Basis rot(ang_vel_axis, ang_vel * delta_time); + new_transform.basis = rot * new_transform.basis; + new_transform.orthonormalize(); + } + + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform); + + // Propagate transform change to node. + set_ignore_transform_notification(true); + set_global_transform(new_transform); + set_ignore_transform_notification(false); + _on_transform_changed(); + } +} + void StaticBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody3D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody3D::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody3D::get_constant_angular_velocity); + ClassDB::bind_method(D_METHOD("set_kinematic_motion_enabled", "enabled"), &StaticBody3D::set_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("is_kinematic_motion_enabled"), &StaticBody3D::is_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody3D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody3D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); - ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); - ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "kinematic_motion"), "set_kinematic_motion_enabled", "is_kinematic_motion_enabled"); +} + +void StaticBody3D::_direct_state_changed(Object *p_state) { +#ifdef DEBUG_ENABLED + PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); + ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); +#else + PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it +#endif + + linear_velocity = state->get_linear_velocity(); + angular_velocity = state->get_angular_velocity(); } StaticBody3D::StaticBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { } -StaticBody3D::~StaticBody3D() {} - void StaticBody3D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_BOUNCE, 0); @@ -161,6 +325,27 @@ void StaticBody3D::_reload_physics_characteristics() { } } +void StaticBody3D::_update_kinematic_motion() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &StaticBody3D::_direct_state_changed)); + + if (!constant_angular_velocity.is_equal_approx(Vector3()) || !constant_linear_velocity.is_equal_approx(Vector3())) { + set_physics_process_internal(true); + return; + } + } else { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), Callable()); + } + + set_physics_process_internal(false); +} + void RigidBody3D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -398,15 +583,15 @@ void RigidBody3D::_notification(int p_what) { void RigidBody3D::set_mode(Mode p_mode) { mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + case MODE_DYNAMIC: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); } break; case MODE_STATIC: { PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); } break; - case MODE_CHARACTER: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_CHARACTER); + case MODE_DYNAMIC_LOCKED: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED); } break; case MODE_KINEMATIC: { @@ -627,14 +812,6 @@ bool RigidBody3D::is_contact_monitor_enabled() const { return contact_monitor != nullptr; } -void RigidBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool RigidBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - Array RigidBody3D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); @@ -654,12 +831,12 @@ Array RigidBody3D::get_colliding_bodies() const { } TypedArray<String> RigidBody3D::get_configuration_warnings() const { - Transform t = get_transform(); + Transform3D t = get_transform(); TypedArray<String> warnings = Node::get_configuration_warnings(); - if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { - warnings.push_back(TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + if ((get_mode() == MODE_DYNAMIC || get_mode() == MODE_DYNAMIC_LOCKED) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { + warnings.push_back(TTR("Size changes to RigidBody3D (in dynamic modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -720,14 +897,11 @@ void RigidBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody3D::get_axis_lock); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody3D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState3D"))); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -737,13 +911,6 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); @@ -757,14 +924,14 @@ void RigidBody3D::_bind_methods() { ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); - BIND_ENUM_CONSTANT(MODE_RIGID); + BIND_ENUM_CONSTANT(MODE_DYNAMIC); BIND_ENUM_CONSTANT(MODE_STATIC); - BIND_ENUM_CONSTANT(MODE_CHARACTER); + BIND_ENUM_CONSTANT(MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(MODE_KINEMATIC); } RigidBody3D::RigidBody3D() : - PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { + PhysicsBody3D(PhysicsServer3D::BODY_MODE_DYNAMIC) { PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &RigidBody3D::_direct_state_changed)); } @@ -784,147 +951,92 @@ void RigidBody3D::_reload_physics_characteristics() { } } -////////////////////////////////////////////////////// -////////////////////////// - -Ref<KinematicCollision3D> KinematicBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { - if (motion_cache.is_null()) { - motion_cache.instance(); - motion_cache->owner = this; - } - - motion_cache->collision = col; - - return motion_cache; - } - - return Ref<KinematicCollision3D>(); -} - -Vector3 KinematicBody3D::get_linear_velocity() const { - return linear_velocity; -} - -Vector3 KinematicBody3D::get_angular_velocity() const { - return angular_velocity; -} - -bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - Transform gt = get_global_transform(); - PhysicsServer3D::MotionResult result; - bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); - - if (colliding) { - r_collision.collider_metadata = result.collider_metadata; - r_collision.collider_shape = result.collider_shape; - r_collision.collider_vel = result.collider_velocity; - r_collision.collision = result.collision_point; - r_collision.normal = result.collision_normal; - r_collision.collider = result.collider_id; - r_collision.collider_rid = result.collider; - r_collision.travel = result.motion; - r_collision.remainder = result.remainder; - r_collision.local_shape = result.collision_local_shape; - } - - for (int i = 0; i < 3; i++) { - if (locked_axis & (1 << i)) { - result.motion[i] = 0; - } - } - - if (!p_test_only) { - gt.origin += result.motion; - set_global_transform(gt); - } - - return colliding; -} +/////////////////////////////////////// //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 body_velocity = p_linear_velocity; - Vector3 body_velocity_normal = body_velocity.normalized(); - Vector3 up_direction = p_up_direction.normalized(); +void CharacterBody3D::move_and_slide() { + Vector3 body_velocity_normal = linear_velocity.normalized(); + + bool was_on_floor = on_floor; for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { - body_velocity[i] = 0; + linear_velocity[i] = 0.0; } } // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector3 motion = (floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); + Vector3 motion = (floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_normal = Vector3(); floor_velocity = Vector3(); - while (p_max_slides) { - Collision collision; + int slide_count = max_slides; + while (slide_count) { + PhysicsServer3D::MotionResult result; bool found_collision = false; for (int i = 0; i < 2; ++i) { bool collided; if (i == 0) { //collide - collided = move_and_collide(motion, p_infinite_inertia, collision); + collided = move_and_collide(motion, infinite_inertia, result, margin); if (!collided) { motion = Vector3(); //clear because no collision happened and motion completed } } else { //separate raycasts (if any) - collided = separate_raycast_shapes(p_infinite_inertia, collision); + collided = separate_raycast_shapes(result); if (collided) { - collision.remainder = motion; //keep - collision.travel = Vector3(); + result.remainder = motion; //keep + result.motion = Vector3(); } } if (collided) { found_collision = true; - colliders.push_back(collision); - motion = collision.remainder; + motion_results.push_back(result); + motion = result.remainder; if (up_direction == Vector3()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; - floor_normal = collision.normal; - on_floor_body = collision.collider_rid; - floor_velocity = collision.collider_vel; - - if (p_stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) { - Transform gt = get_global_transform(); - gt.origin -= collision.travel.slide(up_direction); + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + + if (stop_on_slope) { + if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) { + Transform3D gt = get_global_transform(); + gt.origin -= result.motion.slide(up_direction); set_global_transform(gt); - return Vector3(); + linear_velocity = Vector3(); + return; } } - } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; } } - motion = motion.slide(collision.normal); - body_velocity = body_velocity.slide(collision.normal); + motion = motion.slide(result.collision_normal); + linear_velocity = linear_velocity.slide(result.collision_normal); for (int j = 0; j < 3; j++) { if (locked_axis & (1 << j)) { - body_velocity[j] = 0; + linear_velocity[j] = 0.0; } } } @@ -934,83 +1046,47 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const break; } - --p_max_slides; + --slide_count; } - return body_velocity; -} - -Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 up_direction = p_up_direction.normalized(); - bool was_on_floor = on_floor; - - Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); - if (!was_on_floor || p_snap == Vector3()) { - return ret; + if (!was_on_floor || snap == Vector3()) { + return; } - Collision col; - Transform gt = get_global_transform(); - - if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + // Apply snap. + Transform3D gt = get_global_transform(); + PhysicsServer3D::MotionResult result; + if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { bool apply = true; if (up_direction != Vector3()) { - if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { on_floor = true; - floor_normal = col.normal; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; - if (p_stop_on_slope) { + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = col.travel.project(up_direction); + result.motion = result.motion.project(up_direction); } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. } } if (apply) { - gt.origin += col.travel; + gt.origin += result.motion; set_global_transform(gt); } } - - return ret; -} - -bool KinematicBody3D::is_on_floor() const { - return on_floor; -} - -bool KinematicBody3D::is_on_wall() const { - return on_wall; } -bool KinematicBody3D::is_on_ceiling() const { - return on_ceiling; -} - -Vector3 KinematicBody3D::get_floor_normal() const { - return floor_normal; -} - -Vector3 KinematicBody3D::get_floor_velocity() const { - return floor_velocity; -} - -bool KinematicBody3D::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); - - return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia); -} - -bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { +bool CharacterBody3D::separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result) { PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); Vector3 recover; - int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); + int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; real_t deepest_depth; for (int i = 0; i < hits; i++) { @@ -1024,15 +1100,15 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision set_global_transform(gt); if (deepest != -1) { - r_collision.collider = sep_res[deepest].collider_id; - r_collision.collider_metadata = sep_res[deepest].collider_metadata; - r_collision.collider_shape = sep_res[deepest].collider_shape; - r_collision.collider_vel = sep_res[deepest].collider_velocity; - r_collision.collision = sep_res[deepest].collision_point; - r_collision.normal = sep_res[deepest].collision_normal; - r_collision.local_shape = sep_res[deepest].collision_local_shape; - r_collision.travel = recover; - r_collision.remainder = Vector3(); + r_result.collider_id = sep_res[deepest].collider_id; + r_result.collider_metadata = sep_res[deepest].collider_metadata; + r_result.collider_shape = sep_res[deepest].collider_shape; + r_result.collider_velocity = sep_res[deepest].collider_velocity; + r_result.collision_point = sep_res[deepest].collision_point; + r_result.collision_normal = sep_res[deepest].collision_normal; + r_result.collision_local_shape = sep_res[deepest].collision_local_shape; + r_result.motion = recover; + r_result.remainder = Vector3(); return true; } else { @@ -1040,39 +1116,53 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision } } -void KinematicBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - if (p_lock) { - locked_axis |= p_axis; - } else { - locked_axis &= (~p_axis); - } - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +void CharacterBody3D::set_safe_margin(real_t p_margin) { + margin = p_margin; } -bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +real_t CharacterBody3D::get_safe_margin() const { + return margin; } -void KinematicBody3D::set_safe_margin(real_t p_margin) { - margin = p_margin; - PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); +Vector3 CharacterBody3D::get_linear_velocity() const { + return linear_velocity; } -real_t KinematicBody3D::get_safe_margin() const { - return margin; +void CharacterBody3D::set_linear_velocity(const Vector3 &p_velocity) { + linear_velocity = p_velocity; +} + +bool CharacterBody3D::is_on_floor() const { + return on_floor; +} + +bool CharacterBody3D::is_on_wall() const { + return on_wall; +} + +bool CharacterBody3D::is_on_ceiling() const { + return on_ceiling; } -int KinematicBody3D::get_slide_count() const { - return colliders.size(); +Vector3 CharacterBody3D::get_floor_normal() const { + return floor_normal; +} + +Vector3 CharacterBody3D::get_floor_velocity() const { + return floor_velocity; +} + +int CharacterBody3D::get_slide_count() const { + return motion_results.size(); } -KinematicBody3D::Collision KinematicBody3D::get_slide_collision(int p_bounce) const { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); - return colliders[p_bounce]; +PhysicsServer3D::MotionResult CharacterBody3D::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), PhysicsServer3D::MotionResult()); + return motion_results[p_bounce]; } -Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision3D>()); +Ref<KinematicCollision3D> CharacterBody3D::_get_slide_collision(int p_bounce) { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), Ref<KinematicCollision3D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); } @@ -1082,75 +1172,126 @@ Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { slide_colliders.write[p_bounce]->owner = this; } - slide_colliders.write[p_bounce]->collision = colliders[p_bounce]; + slide_colliders.write[p_bounce]->result = motion_results[p_bounce]; return slide_colliders[p_bounce]; } -void KinematicBody3D::_notification(int p_what) { +bool CharacterBody3D::is_stop_on_slope_enabled() const { + return stop_on_slope; +} + +void CharacterBody3D::set_stop_on_slope_enabled(bool p_enabled) { + stop_on_slope = p_enabled; +} + +bool CharacterBody3D::is_infinite_inertia_enabled() const { + return infinite_inertia; +} +void CharacterBody3D::set_infinite_inertia_enabled(bool p_enabled) { + infinite_inertia = p_enabled; +} + +int CharacterBody3D::get_max_slides() const { + return max_slides; +} + +void CharacterBody3D::set_max_slides(int p_max_slides) { + ERR_FAIL_COND(p_max_slides > 0); + max_slides = p_max_slides; +} + +real_t CharacterBody3D::get_floor_max_angle() const { + return floor_max_angle; +} + +void CharacterBody3D::set_floor_max_angle(real_t p_radians) { + floor_max_angle = p_radians; +} + +real_t CharacterBody3D::get_floor_max_angle_degrees() const { + return Math::rad2deg(floor_max_angle); +} + +void CharacterBody3D::set_floor_max_angle_degrees(real_t p_degrees) { + floor_max_angle = Math::deg2rad(p_degrees); +} + +const Vector3 &CharacterBody3D::get_snap() const { + return snap; +} + +void CharacterBody3D::set_snap(const Vector3 &p_snap) { + snap = p_snap; +} + +const Vector3 &CharacterBody3D::get_up_direction() const { + return up_direction; +} + +void CharacterBody3D::set_up_direction(const Vector3 &p_up_direction) { + up_direction = p_up_direction.normalized(); +} + +void CharacterBody3D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { // Reset move_and_slide() data. on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_velocity = Vector3(); } } -void KinematicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true)); +void CharacterBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); - ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody3D::is_on_floor); - ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody3D::is_on_ceiling); - ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody3D::is_on_wall); - ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody3D::get_floor_normal); - ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody3D::get_floor_velocity); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody3D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody3D::get_linear_velocity); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &KinematicBody3D::get_axis_lock); + ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin); + ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody3D::is_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody3D::set_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody3D::is_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody3D::set_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody3D::get_max_slides); + ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides); + ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody3D::get_floor_max_angle); + ClassDB::bind_method(D_METHOD("set_floor_max_angle", "radians"), &CharacterBody3D::set_floor_max_angle); + ClassDB::bind_method(D_METHOD("get_floor_max_angle_degrees"), &CharacterBody3D::get_floor_max_angle_degrees); + ClassDB::bind_method(D_METHOD("set_floor_max_angle_degrees", "degrees"), &CharacterBody3D::set_floor_max_angle_degrees); + ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody3D::get_snap); + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody3D::set_snap); + ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody3D::get_up_direction); + ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody3D::set_up_direction); - ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody3D::set_safe_margin); - ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody3D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_ceiling"), &CharacterBody3D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody3D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody3D::get_floor_normal); + ClassDB::bind_method(D_METHOD("get_floor_velocity"), &CharacterBody3D::get_floor_velocity); - ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody3D::get_slide_count); - ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody3D::_get_slide_collision); - - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ClassDB::bind_method(D_METHOD("get_slide_count"), &CharacterBody3D::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody3D::_get_slide_collision); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides"), "set_max_slides", "get_max_slides"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_floor_max_angle", "get_floor_max_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle_degrees", PROPERTY_HINT_RANGE, "0,180,0.1", PROPERTY_USAGE_EDITOR), "set_floor_max_angle_degrees", "get_floor_max_angle_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } -void KinematicBody3D::_direct_state_changed(Object *p_state) { -#ifdef DEBUG_ENABLED - PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); - ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); -#else - PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it -#endif - - linear_velocity = state->get_linear_velocity(); - angular_velocity = state->get_angular_velocity(); -} - -KinematicBody3D::KinematicBody3D() : +CharacterBody3D::CharacterBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - set_safe_margin(0.001); - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &KinematicBody3D::_direct_state_changed)); } -KinematicBody3D::~KinematicBody3D() { - if (motion_cache.is_valid()) { - motion_cache->owner = nullptr; - } - +CharacterBody3D::~CharacterBody3D() { for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { slide_colliders.write[i]->owner = nullptr; @@ -1161,39 +1302,39 @@ KinematicBody3D::~KinematicBody3D() { /////////////////////////////////////// Vector3 KinematicCollision3D::get_position() const { - return collision.collision; + return result.collision_point; } Vector3 KinematicCollision3D::get_normal() const { - return collision.normal; + return result.collision_normal; } Vector3 KinematicCollision3D::get_travel() const { - return collision.travel; + return result.motion; } Vector3 KinematicCollision3D::get_remainder() const { - return collision.remainder; + return result.remainder; } Object *KinematicCollision3D::get_local_shape() const { if (!owner) { return nullptr; } - uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + uint32_t ownerid = owner->shape_find_owner(result.collision_local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision3D::get_collider() const { - if (collision.collider.is_valid()) { - return ObjectDB::get_instance(collision.collider); + if (result.collider_id.is_valid()) { + return ObjectDB::get_instance(result.collider_id); } return nullptr; } ObjectID KinematicCollision3D::get_collider_id() const { - return collision.collider; + return result.collider_id; } Object *KinematicCollision3D::get_collider_shape() const { @@ -1201,7 +1342,7 @@ Object *KinematicCollision3D::get_collider_shape() const { if (collider) { CollisionObject3D *obj2d = Object::cast_to<CollisionObject3D>(collider); if (obj2d) { - uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + uint32_t ownerid = obj2d->shape_find_owner(result.collider_shape); return obj2d->shape_owner_get_owner(ownerid); } } @@ -1210,11 +1351,11 @@ Object *KinematicCollision3D::get_collider_shape() const { } int KinematicCollision3D::get_collider_shape_index() const { - return collision.collider_shape; + return result.collider_shape; } Vector3 KinematicCollision3D::get_collider_velocity() const { - return collision.collider_vel; + return result.collider_velocity; } Variant KinematicCollision3D::get_collider_metadata() const { @@ -1247,12 +1388,6 @@ void KinematicCollision3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); } -KinematicCollision3D::KinematicCollision3D() { - collision.collider_shape = 0; - collision.local_shape = 0; - owner = nullptr; -} - /////////////////////////////////////// bool PhysicalBone3D::JointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -1989,7 +2124,7 @@ void PhysicalBone3D::_direct_state_changed(Object *p_state) { state = (PhysicsDirectBodyState3D *)p_state; //trust it #endif - Transform global_transform(state->get_transform()); + Transform3D global_transform(state->get_transform()); set_ignore_transform_notification(true); set_global_transform(global_transform); @@ -2048,16 +2183,13 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); - ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset"), "set_joint_offset", "get_joint_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset"), "set_body_offset", "get_body_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); @@ -2067,14 +2199,6 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); - BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); BIND_ENUM_CONSTANT(JOINT_TYPE_CONE); @@ -2124,8 +2248,8 @@ void PhysicalBone3D::_reload_joint() { return; } - Transform joint_transf = get_global_transform() * joint_offset; - Transform local_a = body_a->get_global_transform().affine_inverse() * joint_transf; + Transform3D joint_transf = get_global_transform() * joint_offset; + Transform3D local_a = body_a->get_global_transform().affine_inverse() * joint_transf; local_a.orthonormalize(); switch (get_joint_type()) { @@ -2218,11 +2342,11 @@ void PhysicalBone3D::_set_gizmo_move_joint(bool p_move_joint) { } #ifdef TOOLS_ENABLED -Transform PhysicalBone3D::get_global_gizmo_transform() const { +Transform3D PhysicalBone3D::get_global_gizmo_transform() const { return gizmo_move_joint ? get_global_transform() * joint_offset : get_global_transform(); } -Transform PhysicalBone3D::get_local_gizmo_transform() const { +Transform3D PhysicalBone3D::get_local_gizmo_transform() const { return gizmo_move_joint ? get_transform() * joint_offset : get_transform(); } #endif @@ -2278,13 +2402,13 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { return joint_data ? joint_data->get_joint_type() : JOINT_TYPE_NONE; } -void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { +void PhysicalBone3D::set_joint_offset(const Transform3D &p_offset) { joint_offset = p_offset; _update_joint_offset(); } -const Transform &PhysicalBone3D::get_joint_offset() const { +const Transform3D &PhysicalBone3D::get_joint_offset() const { return joint_offset; } @@ -2306,11 +2430,11 @@ Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { return get_joint_rotation() * (180.0 / Math_PI); } -const Transform &PhysicalBone3D::get_body_offset() const { +const Transform3D &PhysicalBone3D::get_body_offset() const { return body_offset; } -void PhysicalBone3D::set_body_offset(const Transform &p_offset) { +void PhysicalBone3D::set_body_offset(const Transform3D &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); @@ -2416,14 +2540,6 @@ bool PhysicalBone3D::is_able_to_sleep() const { return can_sleep; } -void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { joint = PhysicsServer3D::get_singleton()->joint_create(); @@ -2463,7 +2579,7 @@ void PhysicalBone3D::update_bone_id() { void PhysicalBone3D::update_offset() { #ifdef TOOLS_ENABLED if (parent_skeleton) { - Transform bone_transform(parent_skeleton->get_global_transform()); + Transform3D bone_transform(parent_skeleton->get_global_transform()); if (-1 != bone_id) { bone_transform *= parent_skeleton->get_bone_global_pose(bone_id); } @@ -2483,7 +2599,7 @@ void PhysicalBone3D::_start_physics_simulation() { return; } reset_to_rest_position(); - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &PhysicalBone3D::_direct_state_changed)); @@ -2506,7 +2622,7 @@ void PhysicalBone3D::_stop_physics_simulation() { } if (_internal_simulate_physics) { PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), Callable()); - parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false); + parent_skeleton->set_bone_global_pose_override(bone_id, Transform3D(), 0.0, false); set_as_top_level(false); _internal_simulate_physics = false; } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 818ff97730..a25cb06bc3 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -37,6 +37,8 @@ #include "servers/physics_server_3d.h" #include "skeleton_3d.h" +class KinematicCollision3D; + class PhysicsBody3D : public CollisionObject3D { GDCLASS(PhysicsBody3D, CollisionObject3D); @@ -44,7 +46,19 @@ protected: static void _bind_methods(); PhysicsBody3D(PhysicsServer3D::BodyMode p_mode); + Ref<KinematicCollision3D> motion_cache; + + uint16_t locked_axis = 0; + + Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001); + public: + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false); + bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001); + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + virtual Vector3 get_linear_velocity() const; virtual Vector3 get_angular_velocity() const; virtual real_t get_inverse_mass() const; @@ -53,7 +67,7 @@ public: void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); - PhysicsBody3D(); + virtual ~PhysicsBody3D(); }; class StaticBody3D : public PhysicsBody3D { @@ -62,11 +76,19 @@ class StaticBody3D : public PhysicsBody3D { Vector3 constant_linear_velocity; Vector3 constant_angular_velocity; + Vector3 linear_velocity; + Vector3 angular_velocity; + Ref<PhysicsMaterial> physics_material_override; + bool kinematic_motion = false; + protected: + void _notification(int p_what); static void _bind_methods(); + void _direct_state_changed(Object *p_state); + public: void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -77,11 +99,18 @@ public: Vector3 get_constant_linear_velocity() const; Vector3 get_constant_angular_velocity() const; + virtual Vector3 get_linear_velocity() const override; + virtual Vector3 get_angular_velocity() const override; + StaticBody3D(); - ~StaticBody3D(); private: void _reload_physics_characteristics(); + + void _update_kinematic_motion(); + + void set_kinematic_motion_enabled(bool p_enabled); + bool is_kinematic_motion_enabled() const; }; class RigidBody3D : public PhysicsBody3D { @@ -89,16 +118,16 @@ class RigidBody3D : public PhysicsBody3D { public: enum Mode { - MODE_RIGID, + MODE_DYNAMIC, MODE_STATIC, - MODE_CHARACTER, + MODE_DYNAMIC_LOCKED, MODE_KINEMATIC, }; protected: bool can_sleep = true; PhysicsDirectBodyState3D *state = nullptr; - Mode mode = MODE_RIGID; + Mode mode = MODE_DYNAMIC; real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; @@ -212,9 +241,6 @@ public: void set_use_continuous_collision_detection(bool p_enable); bool is_using_continuous_collision_detection() const; - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - Array get_colliding_bodies() const; void add_central_force(const Vector3 &p_force); @@ -238,30 +264,20 @@ VARIANT_ENUM_CAST(RigidBody3D::Mode); class KinematicCollision3D; -class KinematicBody3D : public PhysicsBody3D { - GDCLASS(KinematicBody3D, PhysicsBody3D); - -public: - struct Collision { - Vector3 collision; - Vector3 normal; - Vector3 collider_vel; - ObjectID collider; - RID collider_rid; - int collider_shape = 0; - Variant collider_metadata; - Vector3 remainder; - Vector3 travel; - int local_shape = 0; - }; +class CharacterBody3D : public PhysicsBody3D { + GDCLASS(CharacterBody3D, PhysicsBody3D); private: - Vector3 linear_velocity; - Vector3 angular_velocity; + real_t margin = 0.001; - uint16_t locked_axis = 0; + bool stop_on_slope = false; + bool infinite_inertia = true; + int max_slides = 4; + real_t floor_max_angle = Math::deg2rad((real_t)45.0); + Vector3 snap; + Vector3 up_direction = Vector3(0.0, 1.0, 0.0); - real_t margin; + Vector3 linear_velocity; Vector3 floor_normal; Vector3 floor_velocity; @@ -269,38 +285,47 @@ private: bool on_floor = false; bool on_ceiling = false; bool on_wall = false; - Vector<Collision> colliders; + Vector<PhysicsServer3D::MotionResult> motion_results; Vector<Ref<KinematicCollision3D>> slide_colliders; - Ref<KinematicCollision3D> motion_cache; - - _FORCE_INLINE_ bool _ignores_mode(PhysicsServer3D::BodyMode) const; - Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision3D> _get_slide_collision(int p_bounce); -protected: - void _notification(int p_what); - static void _bind_methods(); + bool separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result); - virtual void _direct_state_changed(Object *p_state); + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; -public: - virtual Vector3 get_linear_velocity() const override; - virtual Vector3 get_angular_velocity() const override; + bool is_stop_on_slope_enabled() const; + void set_stop_on_slope_enabled(bool p_enabled); - bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false); - bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia); + bool is_infinite_inertia_enabled() const; + void set_infinite_inertia_enabled(bool p_enabled); - bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); + int get_max_slides() const; + void set_max_slides(int p_max_slides); - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + real_t get_floor_max_angle() const; + void set_floor_max_angle(real_t p_radians); - void set_safe_margin(real_t p_margin); - real_t get_safe_margin() const; + real_t get_floor_max_angle_degrees() const; + void set_floor_max_angle_degrees(real_t p_degrees); + + const Vector3 &get_snap() const; + void set_snap(const Vector3 &p_snap); + + const Vector3 &get_up_direction() const; + void set_up_direction(const Vector3 &p_up_direction); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void move_and_slide(); + + virtual Vector3 get_linear_velocity() const override; + void set_linear_velocity(const Vector3 &p_velocity); - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -308,18 +333,19 @@ public: Vector3 get_floor_velocity() const; int get_slide_count() const; - Collision get_slide_collision(int p_bounce) const; + PhysicsServer3D::MotionResult get_slide_collision(int p_bounce) const; - KinematicBody3D(); - ~KinematicBody3D(); + CharacterBody3D(); + ~CharacterBody3D(); }; class KinematicCollision3D : public Reference { GDCLASS(KinematicCollision3D, Reference); - KinematicBody3D *owner; - friend class KinematicBody3D; - KinematicBody3D::Collision collision; + PhysicsBody3D *owner = nullptr; + friend class PhysicsBody3D; + friend class CharacterBody3D; + PhysicsServer3D::MotionResult result; protected: static void _bind_methods(); @@ -336,8 +362,6 @@ public: int get_collider_shape_index() const; Vector3 get_collider_velocity() const; Variant get_collider_metadata() const; - - KinematicCollision3D(); }; class PhysicalBone3D : public PhysicsBody3D { @@ -467,12 +491,12 @@ private: #endif JointData *joint_data = nullptr; - Transform joint_offset; + Transform3D joint_offset; RID joint; Skeleton3D *parent_skeleton = nullptr; - Transform body_offset; - Transform body_offset_inverse; + Transform3D body_offset; + Transform3D body_offset_inverse; bool simulate_physics = false; bool _internal_simulate_physics = false; int bone_id = -1; @@ -508,8 +532,8 @@ public: public: #ifdef TOOLS_ENABLED - virtual Transform get_global_gizmo_transform() const override; - virtual Transform get_local_gizmo_transform() const override; + virtual Transform3D get_global_gizmo_transform() const override; + virtual Transform3D get_local_gizmo_transform() const override; #endif const JointData *get_joint_data() const; @@ -520,8 +544,8 @@ public: void set_joint_type(JointType p_joint_type); JointType get_joint_type() const; - void set_joint_offset(const Transform &p_offset); - const Transform &get_joint_offset() const; + void set_joint_offset(const Transform3D &p_offset); + const Transform3D &get_joint_offset() const; void set_joint_rotation(const Vector3 &p_euler_rad); Vector3 get_joint_rotation() const; @@ -529,8 +553,8 @@ public: void set_joint_rotation_degrees(const Vector3 &p_euler_deg); Vector3 get_joint_rotation_degrees() const; - void set_body_offset(const Transform &p_offset); - const Transform &get_body_offset() const; + void set_body_offset(const Transform3D &p_offset); + const Transform3D &get_body_offset() const; void set_simulate_physics(bool p_simulate); bool get_simulate_physics(); @@ -560,9 +584,6 @@ public: void set_can_sleep(bool p_active); bool is_able_to_sleep() const; - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 3d58d1c10e..01f10c171f 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -372,15 +372,15 @@ bool HingeJoint3D::get_flag(Flag p_flag) const { } void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D gt = get_global_transform(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -506,15 +506,15 @@ real_t SliderJoint3D::get_param(Param p_param) const { } void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D gt = get_global_transform(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -611,18 +611,18 @@ real_t ConeTwistJoint3D::get_param(Param p_param) const { } void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -936,18 +936,18 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const { } void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 475f8c07fd..db841101e5 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -205,7 +205,7 @@ void RayCast3D::_update_raycast_state() { PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space()); ERR_FAIL_COND(!dss); - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); Vector3 to = target_position; if (to == Vector3()) { diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index 29a407905b..a7b3a6f1ec 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -65,7 +65,7 @@ void RemoteTransform3D::_update_remote() { if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_global_transform(get_global_transform()); } else { - Transform our_trans = get_global_transform(); + Transform3D our_trans = get_global_transform(); if (update_remote_rotation) { n->set_rotation(our_trans.basis.get_rotation()); @@ -76,7 +76,7 @@ void RemoteTransform3D::_update_remote() { } if (update_remote_position) { - Transform n_trans = n->get_global_transform(); + Transform3D n_trans = n->get_global_transform(); n_trans.set_origin(our_trans.get_origin()); n->set_global_transform(n_trans); @@ -87,7 +87,7 @@ void RemoteTransform3D::_update_remote() { if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_transform(get_transform()); } else { - Transform our_trans = get_transform(); + Transform3D our_trans = get_transform(); if (update_remote_rotation) { n->set_rotation(our_trans.basis.get_rotation()); @@ -98,7 +98,7 @@ void RemoteTransform3D::_update_remote() { } if (update_remote_position) { - Transform n_trans = n->get_transform(); + Transform3D n_trans = n->get_transform(); n_trans.set_origin(our_trans.get_origin()); n->set_transform(n_trans); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 82927df5f1..f9d613a4bb 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -135,9 +135,9 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { String prep = "bones/" + itos(i) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, prep + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -211,7 +211,7 @@ void Skeleton3D::_notification(int p_what) { if (b.disable_rest) { if (b.enabled) { - Transform pose = b.pose; + Transform3D pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } @@ -227,14 +227,14 @@ void Skeleton3D::_notification(int p_what) { b.pose_global = bonesptr[b.parent].pose_global; b.pose_global_no_override = bonesptr[b.parent].pose_global; } else { - b.pose_global = Transform(); - b.pose_global_no_override = Transform(); + b.pose_global = Transform3D(); + b.pose_global_no_override = Transform3D(); } } } else { if (b.enabled) { - Transform pose = b.pose; + Transform3D pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } @@ -337,7 +337,6 @@ void Skeleton3D::_notification(int p_what) { } break; -#ifndef _3D_DISABLED case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { // This is active only if the skeleton animates the physical bones // and the state of the bone is not active. @@ -356,7 +355,6 @@ void Skeleton3D::_notification(int p_what) { set_physics_process_internal(true); } } break; -#endif } } @@ -368,7 +366,7 @@ void Skeleton3D::clear_bones_global_pose_override() { _make_dirty(); } -void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) { +void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].global_pose_override_amount = p_amount; bones.write[p_bone].global_pose_override = p_pose; @@ -376,16 +374,16 @@ void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_po _make_dirty(); } -Transform Skeleton3D::get_bone_global_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_global_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); if (dirty) { const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON); } return bones[p_bone].pose_global; } -Transform Skeleton3D::get_bone_global_pose_no_override(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_global_pose_no_override(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); if (dirty) { const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON); } @@ -496,15 +494,14 @@ int Skeleton3D::get_bone_parent(int p_bone) const { return bones[p_bone].parent; } -void Skeleton3D::set_bone_rest(int p_bone, const Transform &p_rest) { +void Skeleton3D::set_bone_rest(int p_bone, const Transform3D &p_rest) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].rest = p_rest; _make_dirty(); } - -Transform Skeleton3D::get_bone_rest(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_rest(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].rest; } @@ -563,7 +560,7 @@ void Skeleton3D::clear_bones() { // posing api -void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { +void Skeleton3D::set_bone_pose(int p_bone, const Transform3D &p_pose) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].pose = p_pose; @@ -571,24 +568,23 @@ void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { _make_dirty(); } } - -Transform Skeleton3D::get_bone_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].pose; } -void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) { +void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose) { ERR_FAIL_INDEX(p_bone, bones.size()); //ERR_FAIL_COND( !is_inside_scene() ); - bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform()); + bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform3D()); bones.write[p_bone].custom_pose = p_custom_pose; _make_dirty(); } -Transform Skeleton3D::get_bone_custom_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_custom_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].custom_pose; } @@ -623,8 +619,6 @@ void Skeleton3D::localize_rests() { } } -#ifndef _3D_DISABLED - void Skeleton3D::set_animate_physical_bones(bool p_animate) { animate_physical_bones = p_animate; @@ -785,8 +779,6 @@ void Skeleton3D::physical_bones_remove_collision_exception(RID p_exception) { _physical_bones_add_remove_collision_exception(false, this, p_exception); } -#endif // _3D_DISABLED - void Skeleton3D::_skin_changed() { _make_dirty(); } @@ -852,11 +844,11 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { } // helper functions -Transform Skeleton3D::bone_transform_to_world_transform(Transform p_bone_transform) { +Transform3D Skeleton3D::bone_transform_to_world_transform(Transform3D p_bone_transform) { return get_global_transform() * p_bone_transform; } -Transform Skeleton3D::world_transform_to_bone_transform(Transform p_world_transform) { +Transform3D Skeleton3D::world_transform_to_bone_transform(Transform3D p_world_transform) { return get_global_transform().affine_inverse() * p_world_transform; } @@ -900,8 +892,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("bone_transform_to_world_transform", "bone_transform"), &Skeleton3D::bone_transform_to_world_transform); ClassDB::bind_method(D_METHOD("world_transform_to_bone_transform", "world_transform"), &Skeleton3D::world_transform_to_bone_transform); -#ifndef _3D_DISABLED - ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton3D::set_animate_physical_bones); ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton3D::get_animate_physical_bones); @@ -911,7 +901,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &Skeleton3D::physical_bones_remove_collision_exception); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones"); -#endif // _3D_DISABLED #ifdef TOOLS_ENABLED ADD_SIGNAL(MethodInfo("pose_updated")); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 299a4b6a02..9be7dce5d2 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -35,12 +35,9 @@ #include "scene/3d/node_3d.h" #include "scene/resources/skin.h" -#ifndef _3D_DISABLED typedef int BoneId; class PhysicalBone3D; -#endif // _3D_DISABLED - class Skeleton3D; class SkinReference : public Reference { @@ -79,23 +76,21 @@ private: int sort_index = 0; //used for re-sorting process order bool disable_rest = false; - Transform rest; + Transform3D rest; - Transform pose; - Transform pose_global; - Transform pose_global_no_override; + Transform3D pose; + Transform3D pose_global; + Transform3D pose_global_no_override; bool custom_pose_enable = false; - Transform custom_pose; + Transform3D custom_pose; float global_pose_override_amount = 0.0; bool global_pose_override_reset = false; - Transform global_pose_override; + Transform3D global_pose_override; -#ifndef _3D_DISABLED PhysicalBone3D *physical_bone = nullptr; PhysicalBone3D *cache_parent_physical_bone = nullptr; -#endif // _3D_DISABLED List<ObjectID> nodes_bound; }; @@ -146,13 +141,13 @@ public: int get_bone_count() const; - void set_bone_rest(int p_bone, const Transform &p_rest); - Transform get_bone_rest(int p_bone) const; - Transform get_bone_global_pose(int p_bone) const; - Transform get_bone_global_pose_no_override(int p_bone) const; + void set_bone_rest(int p_bone, const Transform3D &p_rest); + Transform3D get_bone_rest(int p_bone) const; + Transform3D get_bone_global_pose(int p_bone) const; + Transform3D get_bone_global_pose_no_override(int p_bone) const; void clear_bones_global_pose_override(); - void set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent = false); + void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent = false); void set_bone_enabled(int p_bone, bool p_enabled); bool is_bone_enabled(int p_bone) const; @@ -165,11 +160,11 @@ public: // posing api - void set_bone_pose(int p_bone, const Transform &p_pose); - Transform get_bone_pose(int p_bone) const; + void set_bone_pose(int p_bone, const Transform3D &p_pose); + Transform3D get_bone_pose(int p_bone) const; - void set_bone_custom_pose(int p_bone, const Transform &p_custom_pose); - Transform get_bone_custom_pose(int p_bone) const; + void set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose); + Transform3D get_bone_custom_pose(int p_bone) const; void localize_rests(); // used for loaders and tools int get_process_order(int p_idx); @@ -178,10 +173,9 @@ public: Ref<SkinReference> register_skin(const Ref<Skin> &p_skin); // Helper functions - Transform bone_transform_to_world_transform(Transform p_transform); - Transform world_transform_to_bone_transform(Transform p_transform); + Transform3D bone_transform_to_world_transform(Transform3D p_transform); + Transform3D world_transform_to_bone_transform(Transform3D p_transform); -#ifndef _3D_DISABLED // Physical bone API void set_animate_physical_bones(bool p_animate); @@ -203,7 +197,6 @@ public: 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 public: Skeleton3D(); diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 294e313300..1005d51e63 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -212,7 +212,7 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_ } } -FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform) { +FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform3D &goal_transform) { FabrikInverseKinematic::EndEffector ee; ee.tip_bone = tip_bone; @@ -236,17 +236,17 @@ void FabrikInverseKinematic::free_task(Task *p_task) { } } -void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) { +void FabrikInverseKinematic::set_goal(Task *p_task, const Transform3D &p_goal) { p_task->goal_global_transform = p_goal; } -void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta) { +void FabrikInverseKinematic::make_goal(Task *p_task, const Transform3D &p_inverse_transf, real_t blending_delta) { if (blending_delta >= 0.99f) { // Update the end_effector (local transform) without blending p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform; } else { // End effector in local transform - const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose_no_override(p_task->end_effectors[0].tip_bone)); + const Transform3D end_effector_pose(p_task->skeleton->get_bone_global_pose_no_override(p_task->end_effectors[0].tip_bone)); // Update the end_effector (local transform) by blending with current pose p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta); @@ -273,7 +273,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Update the initial root transform so its synced with any animation changes _update_chain(p_task->skeleton, &p_task->chain.chain_root); - p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, false); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform3D(), 0.0, false); Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin; make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); @@ -287,7 +287,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Assign new bone position. ChainItem *ci(&p_task->chain.chain_root); while (ci) { - Transform new_bone_pose(ci->initial_transform); + Transform3D new_bone_pose(ci->initial_transform); new_bone_pose.origin = ci->current_pos; if (!ci->children.is_empty()) { @@ -397,7 +397,7 @@ void SkeletonIK3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone"), "set_root_bone", "get_root_bone"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "tip_bone"), "set_tip_bone", "get_tip_bone"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "target"), "set_target_transform", "get_target_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position"); @@ -461,12 +461,12 @@ real_t SkeletonIK3D::get_interpolation() const { return interpolation; } -void SkeletonIK3D::set_target_transform(const Transform &p_target) { +void SkeletonIK3D::set_target_transform(const Transform3D &p_target) { target = p_target; reload_goal(); } -const Transform &SkeletonIK3D::get_target_transform() const { +const Transform3D &SkeletonIK3D::get_target_transform() const { return target; } @@ -537,7 +537,7 @@ void SkeletonIK3D::stop() { } } -Transform SkeletonIK3D::_get_target_transform() { +Transform3D SkeletonIK3D::_get_target_transform() { if (!target_node_override && !target_node_path_override.is_empty()) { target_node_override = Object::cast_to<Node3D>(get_node(target_node_path_override)); } diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 9b5ae240f6..81dfe675c3 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -37,13 +37,13 @@ * @author AndreaCatania */ -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "scene/3d/skeleton_3d.h" class FabrikInverseKinematic { struct EndEffector { BoneId tip_bone; - Transform goal_transform; + Transform3D goal_transform; }; struct ChainItem { @@ -55,7 +55,7 @@ class FabrikInverseKinematic { real_t length = 0.0; /// Positions relative to root bone - Transform initial_transform; + Transform3D initial_transform; Vector3 current_pos; // Direction from this bone to child Vector3 current_ori; @@ -97,7 +97,7 @@ public: BoneId root_bone = -1; Vector<EndEffector> end_effectors; - Transform goal_global_transform; + Transform3D goal_global_transform; Task() {} }; @@ -112,11 +112,11 @@ private: static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos); public: - static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform); + static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform3D &goal_transform); static void free_task(Task *p_task); // The goal of chain should be always in local space - static void set_goal(Task *p_task, const Transform &p_goal); - static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); + static void set_goal(Task *p_task, const Transform3D &p_goal); + static void make_goal(Task *p_task, const Transform3D &p_inverse_transf, real_t blending_delta); static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); static void _update_chain(const Skeleton3D *p_skeleton, ChainItem *p_chain_item); @@ -128,7 +128,7 @@ class SkeletonIK3D : public Node { StringName root_bone; StringName tip_bone; real_t interpolation = 1.0; - Transform target; + Transform3D target; NodePath target_node_path_override; bool override_tip_basis = true; bool use_magnet = false; @@ -161,8 +161,8 @@ public: void set_interpolation(real_t p_interpolation); real_t get_interpolation() const; - void set_target_transform(const Transform &p_target); - const Transform &get_target_transform() const; + void set_target_transform(const Transform3D &p_target); + const Transform3D &get_target_transform() const; void set_target_node(const NodePath &p_node); NodePath get_target_node(); @@ -190,7 +190,7 @@ public: void stop(); private: - Transform _get_target_transform(); + Transform3D _get_target_transform(); void reload_chain(); void reload_goal(); void _solve_chain(); diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index dc4deb0570..df5474d03e 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -283,7 +283,7 @@ void SoftBody3D::_notification(int p_what) { set_notify_transform(false); // Required to be top level with Transform at center of world in order to modify RenderingServer only to support custom Transform set_as_top_level(true); - set_transform(Transform()); + set_transform(Transform3D()); set_notify_transform(true); } break; @@ -373,7 +373,7 @@ TypedArray<String> SoftBody3D::get_configuration_warnings() const { warnings.push_back(TTR("This body will be ignored until you set a mesh.")); } - Transform t = get_transform(); + Transform3D t = get_transform(); if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { warnings.push_back(TTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } @@ -408,7 +408,7 @@ void SoftBody3D::_draw_soft_mesh() { /// Necessary in order to render the mesh correctly (Soft body nodes are in global space) simulation_started = true; call_deferred("set_as_top_level", true); - call_deferred("set_transform", Transform()); + call_deferred("set_transform", Transform3D()); } _update_physics_server(); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 9518b47696..1911e14d54 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -153,7 +153,7 @@ void SpringArm3D::process_spring() { } current_spring_length = spring_length * motion_delta; - Transform childs_transform; + Transform3D childs_transform; childs_transform.origin = get_global_transform().origin + cast_direction * (spring_length * motion_delta); for (int i = get_child_count() - 1; 0 <= i; --i) { diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 9493f686c4..0d88769b70 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -346,7 +346,7 @@ VehicleWheel3D::VehicleWheel3D() { void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) { wheel.m_raycastInfo.m_isInContact = false; - Transform chassisTrans = s->get_transform(); + Transform3D chassisTrans = s->get_transform(); /* if (interpolatedTransform && (getRigidBody()->getMotionState())) { getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); @@ -784,7 +784,7 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) { Vector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; #if defined ROLLING_INFLUENCE_FIX // fix. It only worked if car's up was along Y - VT. - Vector3 vChassisWorldUp = s->get_transform().basis.transposed()[1]; //getRigidBody()->getCenterOfMassTransform().getBasis().getColumn(m_indexUpAxis); + Vector3 vChassisWorldUp = s->get_transform().basis.transposed()[1]; //getRigidBody()->getCenterOfMassTransform3D().getBasis().getColumn(m_indexUpAxis); rel_pos -= vChassisWorldUp * (vChassisWorldUp.dot(rel_pos) * (1.f - wheelInfo.m_rollInfluence)); #else rel_pos[1] *= wheelInfo.m_rollInfluence; //? @@ -841,7 +841,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { Vector3 vel = state->get_linear_velocity() + (state->get_angular_velocity()).cross(relpos); // * mPos); if (wheel.m_raycastInfo.m_isInContact) { - const Transform &chassisWorldTransform = state->get_transform(); + const Transform3D &chassisWorldTransform = state->get_transform(); Vector3 fwd( chassisWorldTransform.basis[0][Vector3::AXIS_Z], diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index 646071a363..2c10205ea3 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -40,8 +40,8 @@ class VehicleWheel3D : public Node3D { friend class VehicleBody3D; - Transform m_worldTransform; - Transform local_xform; + Transform3D m_worldTransform; + Transform3D local_xform; bool engine_traction = false; bool steers = false; diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index 471838b9d1..b230cb2fd7 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -138,7 +138,7 @@ void VisibilityEnabler3D::_find_nodes(Node *p_node) { { RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node); - if (rb && ((rb->get_mode() == RigidBody3D::MODE_CHARACTER || rb->get_mode() == RigidBody3D::MODE_RIGID))) { + if (rb && ((rb->get_mode() == RigidBody3D::MODE_DYNAMIC || rb->get_mode() == RigidBody3D::MODE_DYNAMIC_LOCKED))) { add = true; meta = rb->get_mode(); } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index d81b09b86c..6971c1ce2a 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -61,7 +61,7 @@ void VisualInstance3D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); RenderingServer::get_singleton()->instance_set_transform(instance, gt); } break; case NOTIFICATION_EXIT_WORLD: { diff --git a/scene/3d/gi_probe.cpp b/scene/3d/voxel_gi.cpp index 6505fb1ee8..e00be9204c 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/voxel_gi.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gi_probe.cpp */ +/* voxel_gi.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gi_probe.h" +#include "voxel_gi.h" #include "core/os/os.h" #include "mesh_instance_3d.h" #include "voxelizer.h" -void GIProbeData::_set_data(const Dictionary &p_data) { +void VoxelGIData::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("bounds")); ERR_FAIL_COND(!p_data.has("octree_size")); ERR_FAIL_COND(!p_data.has("octree_cells")); @@ -62,12 +62,12 @@ void GIProbeData::_set_data(const Dictionary &p_data) { octree_df = img->get_data(); } Vector<int> octree_levels = p_data["level_counts"]; - Transform to_cell_xform = p_data["to_cell_xform"]; + Transform3D to_cell_xform = p_data["to_cell_xform"]; allocate(to_cell_xform, bounds, octree_size, octree_cells, octree_data, octree_df, octree_levels); } -Dictionary GIProbeData::_get_data() const { +Dictionary VoxelGIData::_get_data() const { Dictionary d; d["bounds"] = get_bounds(); Vector3i otsize = get_octree_size(); @@ -90,186 +90,186 @@ Dictionary GIProbeData::_get_data() const { return d; } -void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); +void VoxelGIData::allocate(const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { + RS::get_singleton()->voxel_gi_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); bounds = p_aabb; to_cell_xform = p_to_cell_xform; octree_size = p_octree_size; } -AABB GIProbeData::get_bounds() const { +AABB VoxelGIData::get_bounds() const { return bounds; } -Vector3 GIProbeData::get_octree_size() const { +Vector3 VoxelGIData::get_octree_size() const { return octree_size; } -Vector<uint8_t> GIProbeData::get_octree_cells() const { - return RS::get_singleton()->gi_probe_get_octree_cells(probe); +Vector<uint8_t> VoxelGIData::get_octree_cells() const { + return RS::get_singleton()->voxel_gi_get_octree_cells(probe); } -Vector<uint8_t> GIProbeData::get_data_cells() const { - return RS::get_singleton()->gi_probe_get_data_cells(probe); +Vector<uint8_t> VoxelGIData::get_data_cells() const { + return RS::get_singleton()->voxel_gi_get_data_cells(probe); } -Vector<uint8_t> GIProbeData::get_distance_field() const { - return RS::get_singleton()->gi_probe_get_distance_field(probe); +Vector<uint8_t> VoxelGIData::get_distance_field() const { + return RS::get_singleton()->voxel_gi_get_distance_field(probe); } -Vector<int> GIProbeData::get_level_counts() const { - return RS::get_singleton()->gi_probe_get_level_counts(probe); +Vector<int> VoxelGIData::get_level_counts() const { + return RS::get_singleton()->voxel_gi_get_level_counts(probe); } -Transform GIProbeData::get_to_cell_xform() const { +Transform3D VoxelGIData::get_to_cell_xform() const { return to_cell_xform; } -void GIProbeData::set_dynamic_range(float p_range) { - RS::get_singleton()->gi_probe_set_dynamic_range(probe, p_range); +void VoxelGIData::set_dynamic_range(float p_range) { + RS::get_singleton()->voxel_gi_set_dynamic_range(probe, p_range); dynamic_range = p_range; } -float GIProbeData::get_dynamic_range() const { +float VoxelGIData::get_dynamic_range() const { return dynamic_range; } -void GIProbeData::set_propagation(float p_propagation) { - RS::get_singleton()->gi_probe_set_propagation(probe, p_propagation); +void VoxelGIData::set_propagation(float p_propagation) { + RS::get_singleton()->voxel_gi_set_propagation(probe, p_propagation); propagation = p_propagation; } -float GIProbeData::get_propagation() const { +float VoxelGIData::get_propagation() const { return propagation; } -void GIProbeData::set_anisotropy_strength(float p_anisotropy_strength) { - RS::get_singleton()->gi_probe_set_anisotropy_strength(probe, p_anisotropy_strength); +void VoxelGIData::set_anisotropy_strength(float p_anisotropy_strength) { + RS::get_singleton()->voxel_gi_set_anisotropy_strength(probe, p_anisotropy_strength); anisotropy_strength = p_anisotropy_strength; } -float GIProbeData::get_anisotropy_strength() const { +float VoxelGIData::get_anisotropy_strength() const { return anisotropy_strength; } -void GIProbeData::set_energy(float p_energy) { - RS::get_singleton()->gi_probe_set_energy(probe, p_energy); +void VoxelGIData::set_energy(float p_energy) { + RS::get_singleton()->voxel_gi_set_energy(probe, p_energy); energy = p_energy; } -float GIProbeData::get_energy() const { +float VoxelGIData::get_energy() const { return energy; } -void GIProbeData::set_ao(float p_ao) { - RS::get_singleton()->gi_probe_set_ao(probe, p_ao); +void VoxelGIData::set_ao(float p_ao) { + RS::get_singleton()->voxel_gi_set_ao(probe, p_ao); ao = p_ao; } -float GIProbeData::get_ao() const { +float VoxelGIData::get_ao() const { return ao; } -void GIProbeData::set_ao_size(float p_ao_size) { - RS::get_singleton()->gi_probe_set_ao_size(probe, p_ao_size); +void VoxelGIData::set_ao_size(float p_ao_size) { + RS::get_singleton()->voxel_gi_set_ao_size(probe, p_ao_size); ao_size = p_ao_size; } -float GIProbeData::get_ao_size() const { +float VoxelGIData::get_ao_size() const { return ao_size; } -void GIProbeData::set_bias(float p_bias) { - RS::get_singleton()->gi_probe_set_bias(probe, p_bias); +void VoxelGIData::set_bias(float p_bias) { + RS::get_singleton()->voxel_gi_set_bias(probe, p_bias); bias = p_bias; } -float GIProbeData::get_bias() const { +float VoxelGIData::get_bias() const { return bias; } -void GIProbeData::set_normal_bias(float p_normal_bias) { - RS::get_singleton()->gi_probe_set_normal_bias(probe, p_normal_bias); +void VoxelGIData::set_normal_bias(float p_normal_bias) { + RS::get_singleton()->voxel_gi_set_normal_bias(probe, p_normal_bias); normal_bias = p_normal_bias; } -float GIProbeData::get_normal_bias() const { +float VoxelGIData::get_normal_bias() const { return normal_bias; } -void GIProbeData::set_interior(bool p_enable) { - RS::get_singleton()->gi_probe_set_interior(probe, p_enable); +void VoxelGIData::set_interior(bool p_enable) { + RS::get_singleton()->voxel_gi_set_interior(probe, p_enable); interior = p_enable; } -bool GIProbeData::is_interior() const { +bool VoxelGIData::is_interior() const { return interior; } -void GIProbeData::set_use_two_bounces(bool p_enable) { - RS::get_singleton()->gi_probe_set_use_two_bounces(probe, p_enable); +void VoxelGIData::set_use_two_bounces(bool p_enable) { + RS::get_singleton()->voxel_gi_set_use_two_bounces(probe, p_enable); use_two_bounces = p_enable; } -bool GIProbeData::is_using_two_bounces() const { +bool VoxelGIData::is_using_two_bounces() const { return use_two_bounces; } -RID GIProbeData::get_rid() const { +RID VoxelGIData::get_rid() const { return probe; } -void GIProbeData::_validate_property(PropertyInfo &property) const { +void VoxelGIData::_validate_property(PropertyInfo &property) const { if (property.name == "anisotropy_strength") { - bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/global_illumination/gi_probes/anisotropic"); + bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/global_illumination/voxel_gi/anisotropic"); if (!anisotropy_enabled) { property.usage = PROPERTY_USAGE_NOEDITOR; } } } -void GIProbeData::_bind_methods() { - ClassDB::bind_method(D_METHOD("allocate", "to_cell_xform", "aabb", "octree_size", "octree_cells", "data_cells", "distance_field", "level_counts"), &GIProbeData::allocate); +void VoxelGIData::_bind_methods() { + ClassDB::bind_method(D_METHOD("allocate", "to_cell_xform", "aabb", "octree_size", "octree_cells", "data_cells", "distance_field", "level_counts"), &VoxelGIData::allocate); - ClassDB::bind_method(D_METHOD("get_bounds"), &GIProbeData::get_bounds); - ClassDB::bind_method(D_METHOD("get_octree_size"), &GIProbeData::get_octree_size); - ClassDB::bind_method(D_METHOD("get_to_cell_xform"), &GIProbeData::get_to_cell_xform); - ClassDB::bind_method(D_METHOD("get_octree_cells"), &GIProbeData::get_octree_cells); - ClassDB::bind_method(D_METHOD("get_data_cells"), &GIProbeData::get_data_cells); - ClassDB::bind_method(D_METHOD("get_level_counts"), &GIProbeData::get_level_counts); + ClassDB::bind_method(D_METHOD("get_bounds"), &VoxelGIData::get_bounds); + ClassDB::bind_method(D_METHOD("get_octree_size"), &VoxelGIData::get_octree_size); + ClassDB::bind_method(D_METHOD("get_to_cell_xform"), &VoxelGIData::get_to_cell_xform); + ClassDB::bind_method(D_METHOD("get_octree_cells"), &VoxelGIData::get_octree_cells); + ClassDB::bind_method(D_METHOD("get_data_cells"), &VoxelGIData::get_data_cells); + ClassDB::bind_method(D_METHOD("get_level_counts"), &VoxelGIData::get_level_counts); - ClassDB::bind_method(D_METHOD("set_dynamic_range", "dynamic_range"), &GIProbeData::set_dynamic_range); - ClassDB::bind_method(D_METHOD("get_dynamic_range"), &GIProbeData::get_dynamic_range); + ClassDB::bind_method(D_METHOD("set_dynamic_range", "dynamic_range"), &VoxelGIData::set_dynamic_range); + ClassDB::bind_method(D_METHOD("get_dynamic_range"), &VoxelGIData::get_dynamic_range); - ClassDB::bind_method(D_METHOD("set_energy", "energy"), &GIProbeData::set_energy); - ClassDB::bind_method(D_METHOD("get_energy"), &GIProbeData::get_energy); + ClassDB::bind_method(D_METHOD("set_energy", "energy"), &VoxelGIData::set_energy); + ClassDB::bind_method(D_METHOD("get_energy"), &VoxelGIData::get_energy); - ClassDB::bind_method(D_METHOD("set_bias", "bias"), &GIProbeData::set_bias); - ClassDB::bind_method(D_METHOD("get_bias"), &GIProbeData::get_bias); + ClassDB::bind_method(D_METHOD("set_bias", "bias"), &VoxelGIData::set_bias); + ClassDB::bind_method(D_METHOD("get_bias"), &VoxelGIData::get_bias); - ClassDB::bind_method(D_METHOD("set_normal_bias", "bias"), &GIProbeData::set_normal_bias); - ClassDB::bind_method(D_METHOD("get_normal_bias"), &GIProbeData::get_normal_bias); + ClassDB::bind_method(D_METHOD("set_normal_bias", "bias"), &VoxelGIData::set_normal_bias); + ClassDB::bind_method(D_METHOD("get_normal_bias"), &VoxelGIData::get_normal_bias); - ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &GIProbeData::set_propagation); - ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbeData::get_propagation); + ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &VoxelGIData::set_propagation); + ClassDB::bind_method(D_METHOD("get_propagation"), &VoxelGIData::get_propagation); - ClassDB::bind_method(D_METHOD("set_anisotropy_strength", "strength"), &GIProbeData::set_anisotropy_strength); - ClassDB::bind_method(D_METHOD("get_anisotropy_strength"), &GIProbeData::get_anisotropy_strength); + ClassDB::bind_method(D_METHOD("set_anisotropy_strength", "strength"), &VoxelGIData::set_anisotropy_strength); + ClassDB::bind_method(D_METHOD("get_anisotropy_strength"), &VoxelGIData::get_anisotropy_strength); - ClassDB::bind_method(D_METHOD("set_ao", "ao"), &GIProbeData::set_ao); - ClassDB::bind_method(D_METHOD("get_ao"), &GIProbeData::get_ao); + ClassDB::bind_method(D_METHOD("set_ao", "ao"), &VoxelGIData::set_ao); + ClassDB::bind_method(D_METHOD("get_ao"), &VoxelGIData::get_ao); - ClassDB::bind_method(D_METHOD("set_ao_size", "strength"), &GIProbeData::set_ao_size); - ClassDB::bind_method(D_METHOD("get_ao_size"), &GIProbeData::get_ao_size); + ClassDB::bind_method(D_METHOD("set_ao_size", "strength"), &VoxelGIData::set_ao_size); + ClassDB::bind_method(D_METHOD("get_ao_size"), &VoxelGIData::get_ao_size); - ClassDB::bind_method(D_METHOD("set_interior", "interior"), &GIProbeData::set_interior); - ClassDB::bind_method(D_METHOD("is_interior"), &GIProbeData::is_interior); + ClassDB::bind_method(D_METHOD("set_interior", "interior"), &VoxelGIData::set_interior); + ClassDB::bind_method(D_METHOD("is_interior"), &VoxelGIData::is_interior); - ClassDB::bind_method(D_METHOD("set_use_two_bounces", "enable"), &GIProbeData::set_use_two_bounces); - ClassDB::bind_method(D_METHOD("is_using_two_bounces"), &GIProbeData::is_using_two_bounces); + ClassDB::bind_method(D_METHOD("set_use_two_bounces", "enable"), &VoxelGIData::set_use_two_bounces); + ClassDB::bind_method(D_METHOD("is_using_two_bounces"), &VoxelGIData::is_using_two_bounces); - ClassDB::bind_method(D_METHOD("_set_data", "data"), &GIProbeData::_set_data); - ClassDB::bind_method(D_METHOD("_get_data"), &GIProbeData::_get_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &VoxelGIData::_set_data); + ClassDB::bind_method(D_METHOD("_get_data"), &VoxelGIData::_get_data); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); @@ -285,18 +285,18 @@ void GIProbeData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior"); } -GIProbeData::GIProbeData() { - probe = RS::get_singleton()->gi_probe_create(); +VoxelGIData::VoxelGIData() { + probe = RS::get_singleton()->voxel_gi_create(); } -GIProbeData::~GIProbeData() { +VoxelGIData::~VoxelGIData() { RS::get_singleton()->free(probe); } ////////////////////// ////////////////////// -void GIProbe::set_probe_data(const Ref<GIProbeData> &p_data) { +void VoxelGI::set_probe_data(const Ref<VoxelGIData> &p_data) { if (p_data.is_valid()) { RS::get_singleton()->instance_set_base(get_instance(), p_data->get_rid()); } else { @@ -306,37 +306,37 @@ void GIProbe::set_probe_data(const Ref<GIProbeData> &p_data) { probe_data = p_data; } -Ref<GIProbeData> GIProbe::get_probe_data() const { +Ref<VoxelGIData> VoxelGI::get_probe_data() const { return probe_data; } -void GIProbe::set_subdiv(Subdiv p_subdiv) { +void VoxelGI::set_subdiv(Subdiv p_subdiv) { ERR_FAIL_INDEX(p_subdiv, SUBDIV_MAX); subdiv = p_subdiv; update_gizmo(); } -GIProbe::Subdiv GIProbe::get_subdiv() const { +VoxelGI::Subdiv VoxelGI::get_subdiv() const { return subdiv; } -void GIProbe::set_extents(const Vector3 &p_extents) { +void VoxelGI::set_extents(const Vector3 &p_extents) { extents = p_extents; update_gizmo(); } -Vector3 GIProbe::get_extents() const { +Vector3 VoxelGI::get_extents() const { return extents; } -void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { +void VoxelGI::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node); if (mi && mi->get_gi_mode() == GeometryInstance3D::GI_MODE_BAKED && mi->is_visible_in_tree()) { Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform(); if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { PlotMesh pm; @@ -356,7 +356,7 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { if (s->is_visible_in_tree()) { Array meshes = p_at_node->call("get_meshes"); for (int i = 0; i < meshes.size(); i += 2) { - Transform mxf = meshes[i]; + Transform3D mxf = meshes[i]; Ref<Mesh> mesh = meshes[i + 1]; if (!mesh.is_valid()) { continue; @@ -364,7 +364,7 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { PlotMesh pm; @@ -382,11 +382,11 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { } } -GIProbe::BakeBeginFunc GIProbe::bake_begin_function = nullptr; -GIProbe::BakeStepFunc GIProbe::bake_step_function = nullptr; -GIProbe::BakeEndFunc GIProbe::bake_end_function = nullptr; +VoxelGI::BakeBeginFunc VoxelGI::bake_begin_function = nullptr; +VoxelGI::BakeStepFunc VoxelGI::bake_step_function = nullptr; +VoxelGI::BakeEndFunc VoxelGI::bake_end_function = nullptr; -Vector3i GIProbe::get_estimated_cell_size() const { +Vector3i VoxelGI::get_estimated_cell_size() const { static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; int cell_subdiv = subdiv_value[subdiv]; int axis_cell_size[3]; @@ -412,7 +412,7 @@ Vector3i GIProbe::get_estimated_cell_size() const { return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]); } -void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { +void VoxelGI::bake(Node *p_from_node, bool p_create_visual_debug) { static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; p_from_node = p_from_node ? p_from_node : get_parent(); @@ -464,7 +464,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { #endif } else { - Ref<GIProbeData> probe_data = get_probe_data(); + Ref<VoxelGIData> probe_data = get_probe_data(); if (probe_data.is_null()) { probe_data.instance(); @@ -476,7 +476,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { Vector<uint8_t> df = baker.get_sdf_3d_image(); - probe_data->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_giprobe_octree_size(), baker.get_giprobe_octree_cells(), baker.get_giprobe_data_cells(), df, baker.get_giprobe_level_cell_count()); + probe_data->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_voxel_gi_octree_size(), baker.get_voxel_gi_octree_cells(), baker.get_voxel_gi_data_cells(), df, baker.get_voxel_gi_level_cell_count()); set_probe_data(probe_data); #ifdef TOOLS_ENABLED @@ -491,46 +491,46 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { notify_property_list_changed(); //bake property may have changed } -void GIProbe::_debug_bake() { +void VoxelGI::_debug_bake() { bake(nullptr, true); } -AABB GIProbe::get_aabb() const { +AABB VoxelGI::get_aabb() const { return AABB(-extents, extents * 2); } -Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> VoxelGI::get_faces(uint32_t p_usage_flags) const { return Vector<Face3>(); } -TypedArray<String> GIProbe::get_configuration_warnings() const { +TypedArray<String> VoxelGI::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (RenderingServer::get_singleton()->is_low_end()) { - warnings.push_back(TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.")); + warnings.push_back(TTR("VoxelGIs are not supported by the GLES2 video driver.\nUse a LightmapGI instead.")); } else if (probe_data.is_null()) { - warnings.push_back(TTR("No GIProbe data set, so this node is disabled. Bake static objects to enable GI.")); + warnings.push_back(TTR("No VoxelGI data set, so this node is disabled. Bake static objects to enable GI.")); } return warnings; } -void GIProbe::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_probe_data", "data"), &GIProbe::set_probe_data); - ClassDB::bind_method(D_METHOD("get_probe_data"), &GIProbe::get_probe_data); +void VoxelGI::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_probe_data", "data"), &VoxelGI::set_probe_data); + ClassDB::bind_method(D_METHOD("get_probe_data"), &VoxelGI::get_probe_data); - ClassDB::bind_method(D_METHOD("set_subdiv", "subdiv"), &GIProbe::set_subdiv); - ClassDB::bind_method(D_METHOD("get_subdiv"), &GIProbe::get_subdiv); + ClassDB::bind_method(D_METHOD("set_subdiv", "subdiv"), &VoxelGI::set_subdiv); + ClassDB::bind_method(D_METHOD("get_subdiv"), &VoxelGI::get_subdiv); - ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GIProbe::set_extents); - ClassDB::bind_method(D_METHOD("get_extents"), &GIProbe::get_extents); + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &VoxelGI::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &VoxelGI::get_extents); - ClassDB::bind_method(D_METHOD("bake", "from_node", "create_visual_debug"), &GIProbe::bake, DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("debug_bake"), &GIProbe::_debug_bake); + ClassDB::bind_method(D_METHOD("bake", "from_node", "create_visual_debug"), &VoxelGI::bake, DEFVAL(Variant()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("debug_bake"), &VoxelGI::_debug_bake); ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdiv", PROPERTY_HINT_ENUM, "64,128,256,512"), "set_subdiv", "get_subdiv"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "GIProbeData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "VoxelGIData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data"); BIND_ENUM_CONSTANT(SUBDIV_64); BIND_ENUM_CONSTANT(SUBDIV_128); @@ -539,11 +539,11 @@ void GIProbe::_bind_methods() { BIND_ENUM_CONSTANT(SUBDIV_MAX); } -GIProbe::GIProbe() { - gi_probe = RS::get_singleton()->gi_probe_create(); +VoxelGI::VoxelGI() { + voxel_gi = RS::get_singleton()->voxel_gi_create(); set_disable_scale(true); } -GIProbe::~GIProbe() { - RS::get_singleton()->free(gi_probe); +VoxelGI::~VoxelGI() { + RS::get_singleton()->free(voxel_gi); } diff --git a/scene/3d/gi_probe.h b/scene/3d/voxel_gi.h index dac7dd3e17..5b9ee28b33 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/voxel_gi.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gi_probe.h */ +/* voxel_gi.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GIPROBE_H -#define GIPROBE_H +#ifndef VOXEL_GI_H +#define VOXEL_GI_H #include "multimesh_instance_3d.h" #include "scene/3d/visual_instance_3d.h" -class GIProbeData : public Resource { - GDCLASS(GIProbeData, Resource); +class VoxelGIData : public Resource { + GDCLASS(VoxelGIData, Resource); RID probe; void _set_data(const Dictionary &p_data); Dictionary _get_data() const; - Transform to_cell_xform; + Transform3D to_cell_xform; AABB bounds; Vector3 octree_size; @@ -62,14 +62,14 @@ protected: void _validate_property(PropertyInfo &property) const override; public: - void allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); + void allocate(const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); AABB get_bounds() const; Vector3 get_octree_size() const; Vector<uint8_t> get_octree_cells() const; Vector<uint8_t> get_data_cells() const; Vector<uint8_t> get_distance_field() const; Vector<int> get_level_counts() const; - Transform get_to_cell_xform() const; + Transform3D get_to_cell_xform() const; void set_dynamic_range(float p_range); float get_dynamic_range() const; @@ -103,12 +103,12 @@ public: virtual RID get_rid() const override; - GIProbeData(); - ~GIProbeData(); + VoxelGIData(); + ~VoxelGIData(); }; -class GIProbe : public VisualInstance3D { - GDCLASS(GIProbe, VisualInstance3D); +class VoxelGI : public VisualInstance3D { + GDCLASS(VoxelGI, VisualInstance3D); public: enum Subdiv { @@ -125,9 +125,9 @@ public: typedef void (*BakeEndFunc)(); private: - Ref<GIProbeData> probe_data; + Ref<VoxelGIData> probe_data; - RID gi_probe; + RID voxel_gi; Subdiv subdiv = SUBDIV_128; Vector3 extents = Vector3(10, 10, 10); @@ -136,7 +136,7 @@ private: Ref<Material> override_material; Vector<Ref<Material>> instance_materials; Ref<Mesh> mesh; - Transform local_xform; + Transform3D local_xform; }; void _find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes); @@ -150,8 +150,8 @@ public: static BakeStepFunc bake_step_function; static BakeEndFunc bake_end_function; - void set_probe_data(const Ref<GIProbeData> &p_data); - Ref<GIProbeData> get_probe_data() const; + void set_probe_data(const Ref<VoxelGIData> &p_data); + Ref<VoxelGIData> get_probe_data() const; void set_subdiv(Subdiv p_subdiv); Subdiv get_subdiv() const; @@ -167,10 +167,10 @@ public: TypedArray<String> get_configuration_warnings() const override; - GIProbe(); - ~GIProbe(); + VoxelGI(); + ~VoxelGI(); }; -VARIANT_ENUM_CAST(GIProbe::Subdiv) +VARIANT_ENUM_CAST(VoxelGI::Subdiv) -#endif // GIPROBE_H +#endif // VOXEL_GI_H diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 1b9ce0201f..ee0c3fe9b6 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -378,7 +378,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material return mc; } -void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) { +void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) { for (int i = 0; i < p_mesh->get_surface_count(); i++) { if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { continue; //only triangles @@ -647,11 +647,11 @@ void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) { po2_bounds.size[i] = po2_bounds.size[longest_axis]; } - Transform to_bounds; + Transform3D to_bounds; to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis])); to_bounds.origin = po2_bounds.position; - Transform to_grid; + Transform3D to_grid; to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis])); to_cell_space = to_grid * to_bounds.affine_inverse(); @@ -668,19 +668,19 @@ void Voxelizer::end_bake() { //create the data for visual server -int Voxelizer::get_gi_probe_octree_depth() const { +int Voxelizer::get_voxel_gi_octree_depth() const { return cell_subdiv; } -Vector3i Voxelizer::get_giprobe_octree_size() const { +Vector3i Voxelizer::get_voxel_gi_octree_size() const { return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]); } -int Voxelizer::get_giprobe_cell_count() const { +int Voxelizer::get_voxel_gi_cell_count() const { return bake_cells.size(); } -Vector<uint8_t> Voxelizer::get_giprobe_octree_cells() const { +Vector<uint8_t> Voxelizer::get_voxel_gi_octree_cells() const { Vector<uint8_t> data; data.resize((8 * 4) * bake_cells.size()); //8 uint32t values { @@ -700,7 +700,7 @@ Vector<uint8_t> Voxelizer::get_giprobe_octree_cells() const { return data; } -Vector<uint8_t> Voxelizer::get_giprobe_data_cells() const { +Vector<uint8_t> Voxelizer::get_voxel_gi_data_cells() const { Vector<uint8_t> data; data.resize((4 * 4) * bake_cells.size()); //8 uint32t values { @@ -755,7 +755,7 @@ Vector<uint8_t> Voxelizer::get_giprobe_data_cells() const { return data; } -Vector<int> Voxelizer::get_giprobe_level_cell_count() const { +Vector<int> Voxelizer::get_voxel_gi_level_cell_count() const { uint32_t cell_count = bake_cells.size(); const Cell *cells = bake_cells.ptr(); Vector<int> level_count; @@ -819,7 +819,7 @@ static void edt(float *f, int stride, int n) { #undef square Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { - Vector3i octree_size = get_giprobe_octree_size(); + Vector3i octree_size = get_voxel_gi_octree_size(); uint32_t float_count = octree_size.x * octree_size.y * octree_size.z; float *work_memory = memnew_arr(float, float_count); @@ -891,7 +891,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx) { if (p_level == cell_subdiv - 1) { Vector3 center = p_aabb.position + p_aabb.size * 0.5; - Transform xform; + Transform3D xform; xform.origin = center; xform.basis.scale(p_aabb.size * 0.5); p_multimesh->set_instance_transform(idx, xform); @@ -1002,7 +1002,7 @@ Ref<MultiMesh> Voxelizer::create_debug_multimesh() { return mm; } -Transform Voxelizer::get_to_cell_space_xform() const { +Transform3D Voxelizer::get_to_cell_space_xform() const { return to_cell_space; } diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index 87f949e7db..e500d2d4c3 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -93,7 +93,7 @@ private: AABB po2_bounds; int axis_cell_size[3] = {}; - Transform to_cell_space; + Transform3D to_cell_space; int color_scan_cell_width = 4; int bake_texture_size = 128; @@ -114,20 +114,20 @@ private: public: void begin_bake(int p_subdiv, const AABB &p_bounds); - void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material); + void plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material); void end_bake(); - int get_gi_probe_octree_depth() const; - Vector3i get_giprobe_octree_size() const; - int get_giprobe_cell_count() const; - Vector<uint8_t> get_giprobe_octree_cells() const; - Vector<uint8_t> get_giprobe_data_cells() const; - Vector<int> get_giprobe_level_cell_count() const; + int get_voxel_gi_octree_depth() const; + Vector3i get_voxel_gi_octree_size() const; + int get_voxel_gi_cell_count() const; + Vector<uint8_t> get_voxel_gi_octree_cells() const; + Vector<uint8_t> get_voxel_gi_data_cells() const; + Vector<int> get_voxel_gi_level_cell_count() const; Vector<uint8_t> get_sdf_3d_image() const; Ref<MultiMesh> create_debug_multimesh(); - Transform get_to_cell_space_xform() const; + Transform3D get_to_cell_space_xform() const; Voxelizer(); }; diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index b5037f9be7..09662f3e7a 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -397,7 +397,7 @@ void XRAnchor3D::_notification(int p_what) { is_active = false; } else { is_active = true; - Transform transform; + Transform3D transform; // we'll need our world_scale real_t world_scale = xr_server->get_world_scale(); @@ -493,7 +493,7 @@ TypedArray<String> XRAnchor3D::get_configuration_warnings() const { }; Plane XRAnchor3D::get_plane() const { - Vector3 location = get_translation(); + Vector3 location = get_position(); Basis orientation = get_transform().basis; Plane plane(location, orientation.get_axis(1).normalized()); @@ -571,7 +571,7 @@ void XROrigin3D::_notification(int p_what) { Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); if (xr_interface.is_valid() && tracked_camera != nullptr) { // get our positioning transform for our headset - Transform t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); + Transform3D t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform3D()); // now apply this to our camera tracked_camera->set_transform(t); diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 689acdd57b..b8980fd56b 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -80,10 +80,11 @@ void AnimationCache::_update_cache() { Ref<Resource> res; - if (animation->track_get_type(i) == Animation::TYPE_TRANSFORM) { + if (animation->track_get_type(i) == Animation::TYPE_TRANSFORM3D) { +#ifndef _3D_DISABLED if (np.get_subname_count() > 1) { path_cache.push_back(Path()); - ERR_CONTINUE_MSG(animation->track_get_type(i) == Animation::TYPE_TRANSFORM, "Transform tracks can't have a subpath '" + np + "'."); + ERR_CONTINUE_MSG(animation->track_get_type(i) == Animation::TYPE_TRANSFORM3D, "Transform tracks can't have a subpath '" + np + "'."); } Node3D *sp = Object::cast_to<Node3D>(node); @@ -113,8 +114,8 @@ void AnimationCache::_update_cache() { path.skeleton = sk; } - path.spatial = sp; - + path.node_3d = sp; +#endif // _3D_DISABLED } else { if (np.get_subname_count() > 0) { RES res2; @@ -167,7 +168,7 @@ void AnimationCache::_update_cache() { cache_valid = true; } -void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform) { +void AnimationCache::set_track_transform(int p_idx, const Transform3D &p_transform) { if (cache_dirty) { _update_cache(); } @@ -179,14 +180,16 @@ void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform return; } +#ifndef _3D_DISABLED ERR_FAIL_COND(!p.node); - ERR_FAIL_COND(!p.spatial); + ERR_FAIL_COND(!p.node_3d); if (p.skeleton) { p.skeleton->set_bone_pose(p.bone_idx, p_transform); } else { - p.spatial->set_transform(p_transform); + p.node_3d->set_transform(p_transform); } +#endif // _3D_DISABLED } void AnimationCache::set_track_value(int p_idx, const Variant &p_value) { @@ -231,11 +234,11 @@ void AnimationCache::set_all(float p_time, float p_delta) { int tc = animation->get_track_count(); for (int i = 0; i < tc; i++) { switch (animation->track_get_type(i)) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { Vector3 loc, scale; - Quat rot; + Quaternion rot; animation->transform_track_interpolate(i, p_time, &loc, &rot, &scale); - Transform tr(Basis(rot), loc); + Transform3D tr(Basis(rot), loc); tr.basis.scale(scale); set_track_transform(i, tr); diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index 07c9d09ae0..c856e644f7 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -40,9 +40,11 @@ class AnimationCache : public Object { struct Path { RES resource; Object *object = nullptr; - Skeleton3D *skeleton = nullptr; // haxor +#ifndef _3D_DISABLED + Skeleton3D *skeleton = nullptr; + Node3D *node_3d = nullptr; +#endif // _3D_DISABLED Node *node = nullptr; - Node3D *spatial = nullptr; int bone_idx = -1; Vector<StringName> subpath; @@ -67,7 +69,7 @@ protected: static void _bind_methods(); public: - void set_track_transform(int p_idx, const Transform &p_transform); + void set_track_transform(int p_idx, const Transform3D &p_transform); void set_track_value(int p_idx, const Variant &p_value); void call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 0c1798a876..2d565fc47a 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -252,6 +252,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id(); int bone_idx = -1; +#ifndef _3D_DISABLED if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton3D>(child)) { Skeleton3D *sk = Object::cast_to<Skeleton3D>(child); bone_idx = sk->find_bone(a->track_get_path(i).get_subname(0)); @@ -259,6 +260,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov continue; } } +#endif // _3D_DISABLED { if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) { @@ -279,11 +281,12 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov p_anim->node_cache[i]->node = child; p_anim->node_cache[i]->resource = resource; p_anim->node_cache[i]->node_2d = Object::cast_to<Node2D>(child); - if (a->track_get_type(i) == Animation::TYPE_TRANSFORM) { +#ifndef _3D_DISABLED + if (a->track_get_type(i) == Animation::TYPE_TRANSFORM3D) { // special cases and caches for transform tracks - // cache spatial - p_anim->node_cache[i]->spatial = Object::cast_to<Node3D>(child); + // cache node_3d + p_anim->node_cache[i]->node_3d = Object::cast_to<Node3D>(child); // cache skeleton p_anim->node_cache[i]->skeleton = Object::cast_to<Skeleton3D>(child); if (p_anim->node_cache[i]->skeleton) { @@ -294,7 +297,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov if (p_anim->node_cache[i]->bone_idx < 0) { // broken track (nonexistent bone) p_anim->node_cache[i]->skeleton = nullptr; - p_anim->node_cache[i]->spatial = nullptr; + p_anim->node_cache[i]->node_3d = nullptr; ERR_CONTINUE(p_anim->node_cache[i]->bone_idx < 0); } } else { @@ -303,6 +306,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov } } } +#endif // _3D_DISABLED if (a->track_get_type(i) == Animation::TYPE_VALUE) { if (!p_anim->node_cache[i]->property_anim.has(a->track_get_path(i).get_concatenated_subnames())) { @@ -366,13 +370,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float } switch (a->track_get_type(i)) { - case Animation::TYPE_TRANSFORM: { - if (!nc->spatial) { + case Animation::TYPE_TRANSFORM3D: { +#ifndef _3D_DISABLED + if (!nc->node_3d) { continue; } Vector3 loc; - Quat rot; + Quaternion rot; Vector3 scale; Error err = a->transform_track_interpolate(i, p_time, &loc, &rot, &scale); @@ -395,7 +400,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float nc->rot_accum = nc->rot_accum.slerp(rot, p_interp); nc->scale_accum = nc->scale_accum.lerp(scale, p_interp); } - +#endif // _3D_DISABLED } break; case Animation::TYPE_VALUE: { if (!nc->node) { @@ -838,20 +843,21 @@ void AnimationPlayer::_animation_process2(float p_delta, bool p_started) { void AnimationPlayer::_animation_update_transforms() { { - Transform t; + Transform3D t; for (int i = 0; i < cache_update_size; i++) { TrackNodeCache *nc = cache_update[i]; ERR_CONTINUE(nc->accum_pass != accum_pass); t.origin = nc->loc_accum; - t.basis.set_quat_scale(nc->rot_accum, nc->scale_accum); + t.basis.set_quaternion_scale(nc->rot_accum, nc->scale_accum); +#ifndef _3D_DISABLED if (nc->skeleton && nc->bone_idx >= 0) { nc->skeleton->set_bone_pose(nc->bone_idx, t); - - } else if (nc->spatial) { - nc->spatial->set_transform(t); + } else if (nc->node_3d) { + nc->node_3d->set_transform(t); } +#endif // _3D_DISABLED } } @@ -1523,11 +1529,11 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o entry.value = nc->skeleton->get_bone_pose(nc->bone_idx); backup->entries.push_back(entry); } else { - if (nc->spatial) { + if (nc->node_3d) { AnimatedValuesBackup::Entry entry; - entry.object = nc->spatial; + entry.object = nc->node_3d; entry.subpath.push_back("transform"); - entry.value = nc->spatial->get_transform(); + entry.value = nc->node_3d->get_transform(); entry.bone_idx = -1; backup->entries.push_back(entry); } else { diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 2a1821c215..7922635438 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -93,14 +93,16 @@ private: uint32_t id = 0; RES resource; Node *node = nullptr; - Node3D *spatial = nullptr; Node2D *node_2d = nullptr; +#ifndef _3D_DISABLED + Node3D *node_3d = nullptr; Skeleton3D *skeleton = nullptr; +#endif // _3D_DISABLED int bone_idx = -1; // accumulated transforms Vector3 loc_accum; - Quat rot_accum; + Quaternion rot_accum; Vector3 scale_accum; uint64_t accum_pass = 0; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 2ad871ba61..7369713e69 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -581,22 +581,23 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { track = track_value; } break; - case Animation::TYPE_TRANSFORM: { - Node3D *spatial = Object::cast_to<Node3D>(child); + case Animation::TYPE_TRANSFORM3D: { +#ifndef _3D_DISABLED + Node3D *node_3d = Object::cast_to<Node3D>(child); - if (!spatial) { - ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'"); + if (!node_3d) { + ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to Node3D: '" + String(path) + "'"); continue; } TrackCacheTransform *track_xform = memnew(TrackCacheTransform); - track_xform->spatial = spatial; + track_xform->node_3d = node_3d; track_xform->skeleton = nullptr; track_xform->bone_idx = -1; - if (path.get_subname_count() == 1 && Object::cast_to<Skeleton3D>(spatial)) { - Skeleton3D *sk = Object::cast_to<Skeleton3D>(spatial); + if (path.get_subname_count() == 1 && Object::cast_to<Skeleton3D>(node_3d)) { + Skeleton3D *sk = Object::cast_to<Skeleton3D>(node_3d); track_xform->skeleton = sk; int bone_idx = sk->find_bone(path.get_subname(0)); if (bone_idx != -1) { @@ -604,11 +605,11 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { } } - track_xform->object = spatial; + track_xform->object = node_3d; track_xform->object_id = track_xform->object->get_instance_id(); track = track_xform; - +#endif // _3D_DISABLED } break; case Animation::TYPE_METHOD: { TrackCacheMethod *track_method = memnew(TrackCacheMethod); @@ -718,7 +719,7 @@ void AnimationTree::_process_graph(float p_delta) { //check all tracks, see if they need modification - root_motion_transform = Transform(); + root_motion_transform = Transform3D(); if (!root.is_valid()) { ERR_PRINT("AnimationTree: root AnimationNode is not set, disabling playback."); @@ -844,14 +845,15 @@ void AnimationTree::_process_graph(float p_delta) { } switch (track->type) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { +#ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); if (track->root_motion) { if (t->process_pass != process_pass) { t->process_pass = process_pass; t->loc = Vector3(); - t->rot = Quat(); + t->rot = Quaternion(); t->rot_blend_accum = 0; t->scale = Vector3(1, 1, 1); } @@ -866,7 +868,7 @@ void AnimationTree::_process_graph(float p_delta) { } Vector3 loc[2]; - Quat rot[2]; + Quaternion rot[2]; Vector3 scale[2]; if (prev_time > time) { @@ -879,7 +881,7 @@ void AnimationTree::_process_graph(float p_delta) { t->loc += (loc[1] - loc[0]) * blend; t->scale += (scale[1] - scale[0]) * blend; - Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); + Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); t->rot = (t->rot * q).normalized(); prev_time = 0; @@ -894,14 +896,14 @@ void AnimationTree::_process_graph(float p_delta) { t->loc += (loc[1] - loc[0]) * blend; t->scale += (scale[1] - scale[0]) * blend; - Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); + Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); t->rot = (t->rot * q).normalized(); prev_time = 0; } else { Vector3 loc; - Quat rot; + Quaternion rot; Vector3 scale; Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale); @@ -930,7 +932,7 @@ void AnimationTree::_process_graph(float p_delta) { } t->scale = t->scale.lerp(scale, blend); } - +#endif // _3D_DISABLED } break; case Animation::TYPE_VALUE: { TrackCacheValue *t = static_cast<TrackCacheValue *>(track); @@ -1188,13 +1190,14 @@ void AnimationTree::_process_graph(float p_delta) { } switch (track->type) { - case Animation::TYPE_TRANSFORM: { + case Animation::TYPE_TRANSFORM3D: { +#ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); - Transform xform; + Transform3D xform; xform.origin = t->loc; - xform.basis.set_quat_scale(t->rot, t->scale); + xform.basis.set_quaternion_scale(t->rot, t->scale); if (t->root_motion) { root_motion_transform = xform; @@ -1206,9 +1209,9 @@ void AnimationTree::_process_graph(float p_delta) { t->skeleton->set_bone_pose(t->bone_idx, xform); } else if (!t->skeleton) { - t->spatial->set_transform(xform); + t->node_3d->set_transform(xform); } - +#endif // _3D_DISABLED } break; case Animation::TYPE_VALUE: { TrackCacheValue *t = static_cast<TrackCacheValue *>(track); @@ -1311,7 +1314,7 @@ NodePath AnimationTree::get_root_motion_track() const { return root_motion_track; } -Transform AnimationTree::get_root_motion_transform() const { +Transform3D AnimationTree::get_root_motion_transform() const { return root_motion_transform; } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 700ff1cb5b..60e0c7200a 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -184,16 +184,18 @@ private: }; struct TrackCacheTransform : public TrackCache { - Node3D *spatial = nullptr; +#ifndef _3D_DISABLED + Node3D *node_3d = nullptr; Skeleton3D *skeleton = nullptr; +#endif // _3D_DISABLED int bone_idx = -1; Vector3 loc; - Quat rot; + Quaternion rot; float rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { - type = Animation::TYPE_TRANSFORM; + type = Animation::TYPE_TRANSFORM3D; } }; @@ -257,7 +259,7 @@ private: bool started = true; NodePath root_motion_track; - Transform root_motion_transform; + Transform3D root_motion_transform; friend class AnimationNode; bool properties_dirty = true; @@ -308,7 +310,7 @@ public: void set_root_motion_track(const NodePath &p_track); NodePath get_root_motion_track() const; - Transform get_root_motion_transform() const; + Transform3D get_root_motion_transform() const; float get_connection_activity(const StringName &p_path, int p_connection) const; void advance(float p_time); diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 9ee1f32581..b963cf5702 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -82,7 +82,7 @@ void RootMotionView::_notification(int p_what) { } if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { - Transform transform; + Transform3D transform; if (has_node(path)) { Node *node = get_node(path); @@ -103,7 +103,7 @@ void RootMotionView::_notification(int p_what) { } } - if (!first && transform == Transform()) { + if (!first && transform == Transform3D()) { return; } diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index afcff6137f..4cd3c7b443 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -46,7 +46,7 @@ public: bool first = true; bool zero_y = true; - Transform accumulated; + Transform3D accumulated; private: void _notification(int p_what); diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 2030808724..b4e597f75e 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -519,11 +519,11 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = r; } break; - case Variant::QUAT: { + case Variant::QUATERNION: { // Get the quaternian for the initial and delta values - Quat i = initial_val; - Quat d = delta_val; - Quat r; + Quaternion i = initial_val; + Quaternion d = delta_val; + Quaternion r; // Execute the equation on the quaternian values and mutate the r quaternian // This uses the custom APPLY_EQUATION macro defined above @@ -571,11 +571,11 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = r; } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { // Get the transforms for the initial and delta values - Transform i = initial_val; - Transform d = delta_val; - Transform r; + Transform3D i = initial_val; + Transform3D d = delta_val; + Transform3D r; // Execute the equation for each of the transforms and their origin and mutate the r transform // This uses the custom APPLY_EQUATION macro defined above @@ -1202,9 +1202,9 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final delta_val = d; } break; - case Variant::QUAT: + case Variant::QUATERNION: // Convert to quaternianls and find the delta - delta_val = final_val.operator Quat() - initial_val.operator Quat(); + delta_val = final_val.operator Quaternion() - initial_val.operator Quaternion(); break; case Variant::AABB: { @@ -1229,11 +1229,11 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final f.elements[2][2] - i.elements[2][2]); } break; - case Variant::TRANSFORM: { + case Variant::TRANSFORM3D: { // Build a new transform which is the difference between the initial and final values - Transform i = initial_val; - Transform f = final_val; - Transform d; + Transform3D i = initial_val; + Transform3D f = final_val; + Transform3D d; d.set(f.basis.elements[0][0] - i.basis.elements[0][0], f.basis.elements[0][1] - i.basis.elements[0][1], f.basis.elements[0][2] - i.basis.elements[0][2], @@ -1266,10 +1266,10 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final Variant::RECT2, Variant::VECTOR3, Variant::TRANSFORM2D, - Variant::QUAT, + Variant::QUATERNION, Variant::AABB, Variant::BASIS, - Variant::TRANSFORM, + Variant::TRANSFORM3D, Variant::COLOR, }; diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index a1d4adcd41..11ce9b2ddc 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -98,7 +98,7 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } else if (p_msg == "override_camera_3D:transform") { ERR_FAIL_COND_V(p_args.size() < 5, ERR_INVALID_DATA); - Transform transform = p_args[0]; + Transform3D transform = p_args[0]; bool is_perspective = p_args[1]; float size_or_fov = p_args[2]; float near = p_args[3]; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index ac067aa001..66155958cf 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -98,17 +98,14 @@ void BaseButton::_notification(int p_what) { } if (p_what == NOTIFICATION_FOCUS_ENTER) { - status.hovering = true; update(); } if (p_what == NOTIFICATION_FOCUS_EXIT) { if (status.press_attempt) { status.press_attempt = false; - status.hovering = false; update(); } else if (status.hovering) { - status.hovering = false; update(); } } @@ -175,10 +172,9 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) { status.hovering = false; } } - // pressed state should be correct with button_up signal - emit_signal("button_up"); status.press_attempt = false; status.pressing_inside = false; + emit_signal("button_up"); } update(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 0ae1dec46d..5afe813ee0 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -515,7 +515,9 @@ void Control::_notification(int p_notification) { get_viewport()->_gui_remove_control(this); } break; case NOTIFICATION_READY: { +#ifdef DEBUG_ENABLED connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); +#endif } break; case NOTIFICATION_ENTER_CANVAS: { @@ -1579,8 +1581,8 @@ void Control::set_rect(const Rect2 &p_rect) { void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED - if (data.size_warning) { - WARN_PRINT("Adjusting the size of Control nodes before they are fully initialized is unreliable. Consider deferring it with set_deferred()."); + if (data.size_warning && (data.anchor[SIDE_LEFT] != data.anchor[SIDE_RIGHT] || data.anchor[SIDE_TOP] != data.anchor[SIDE_BOTTOM])) { + WARN_PRINT("Nodes with non-equal opposite anchors will have their size overriden after _ready(). \nIf you want to set size, change the anchors or consider using set_deferred()."); } #endif set_size(p_size); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index b6884bd37d..7cae091c57 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -155,7 +155,7 @@ bool AcceptDialog::has_autowrap() { return label->has_autowrap(); } -void AcceptDialog::register_text_enter(Node *p_line_edit) { +void AcceptDialog::register_text_enter(Control *p_line_edit) { ERR_FAIL_NULL(p_line_edit); LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); if (line_edit) { diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index b072055d49..69035001c0 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -77,7 +77,7 @@ public: Label *get_label() { return label; } static void set_swap_cancel_ok(bool p_swap); - void register_text_enter(Node *p_line_edit); + void register_text_enter(Control *p_line_edit); Button *get_ok_button() { return ok; } Button *add_button(const String &p_text, bool p_right = false, const String &p_action = ""); diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 541925a802..a54f5eef06 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -33,7 +33,7 @@ void GridContainer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_SORT_CHILDREN: { - Map<int, int> col_minw; // Max of min_width of all controls in each col (indexed by col). + Map<int, int> col_minw; // Max of min_width of all controls in each col (indexed by col). Map<int, int> row_minh; // Max of min_height of all controls in each row (indexed by row). Set<int> col_expanded; // Columns which have the SIZE_EXPAND flag set. Set<int> row_expanded; // Rows which have the SIZE_EXPAND flag set. diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 471b26be75..11096e7976 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -256,6 +256,7 @@ void Tabs::_notification(int p_what) { _update_cache(); update(); } break; + case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < tabs.size(); ++i) { _shape(i); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index dc7057f339..c39b8005e4 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -491,36 +491,24 @@ bool Node::is_network_master() const { /***** RPC CONFIG ********/ -uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { - uint16_t mid = get_node_rpc_method_id(p_method); - if (mid == UINT16_MAX) { - // It's new - NetData nd; - nd.name = p_method; - nd.mode = p_mode; - data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); - } else { - int c_mid = (~(1 << 15)) & mid; - data.rpc_methods.write[c_mid].mode = p_mode; - return mid; - } -} - -uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { - uint16_t pid = get_node_rset_property_id(p_property); - if (pid == UINT16_MAX) { - // It's new - NetData nd; - nd.name = p_property; - nd.mode = p_mode; - data.rpc_properties.push_back(nd); - return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); - } else { - int c_pid = (~(1 << 15)) & pid; - data.rpc_properties.write[c_pid].mode = p_mode; - return pid; +uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, NetworkedMultiplayerPeer::TransferMode p_transfer_mode, int p_channel) { + for (int i = 0; i < data.rpc_methods.size(); i++) { + if (data.rpc_methods[i].name == p_method) { + MultiplayerAPI::RPCConfig &nd = data.rpc_methods.write[i]; + nd.rpc_mode = p_rpc_mode; + nd.transfer_mode = p_transfer_mode; + nd.channel = p_channel; + return i | (1 << 15); + } } + // New method + MultiplayerAPI::RPCConfig nd; + nd.name = p_method; + nd.rpc_mode = p_rpc_mode; + nd.transfer_mode = p_transfer_mode; + nd.channel = p_channel; + data.rpc_methods.push_back(nd); + return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); } /***** RPC FUNCTIONS ********/ @@ -536,7 +524,7 @@ void Node::rpc(const StringName &p_method, VARIANT_ARG_DECLARE) { argc++; } - rpcp(0, false, p_method, argptr, argc); + rpcp(0, p_method, argptr, argc); } void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) { @@ -550,35 +538,7 @@ void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE argc++; } - rpcp(p_peer_id, false, p_method, argptr, argc); -} - -void Node::rpc_unreliable(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - rpcp(0, true, p_method, argptr, argc); -} - -void Node::rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - rpcp(p_peer_id, true, p_method, argptr, argc); + rpcp(p_peer_id, p_method, argptr, argc); } Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { @@ -597,7 +557,7 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr StringName method = *p_args[0]; - rpcp(0, false, method, &p_args[1], p_argcount - 1); + rpcp(0, method, &p_args[1], p_argcount - 1); r_error.error = Callable::CallError::CALL_OK; return Variant(); @@ -627,92 +587,17 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal int peer_id = *p_args[0]; StringName method = *p_args[1]; - rpcp(peer_id, false, method, &p_args[2], p_argcount - 2); + rpcp(peer_id, method, &p_args[2], p_argcount - 2); r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (p_argcount < 1) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 1; - return Variant(); - } - - if (p_args[0]->get_type() != Variant::STRING_NAME) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING_NAME; - return Variant(); - } - - StringName method = *p_args[0]; - - rpcp(0, true, method, &p_args[1], p_argcount - 1); - - r_error.error = Callable::CallError::CALL_OK; - return Variant(); -} - -Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - if (p_argcount < 2) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 2; - return Variant(); - } - - if (p_args[0]->get_type() != Variant::INT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::INT; - return Variant(); - } - - if (p_args[1]->get_type() != Variant::STRING_NAME) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING_NAME; - return Variant(); - } - - int peer_id = *p_args[0]; - StringName method = *p_args[1]; - - rpcp(peer_id, true, method, &p_args[2], p_argcount - 2); - - r_error.error = Callable::CallError::CALL_OK; - return Variant(); -} - -void Node::rpcp(int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) { - ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->rpcp(this, p_peer_id, p_unreliable, p_method, p_arg, p_argcount); -} - -void Node::rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) { +void Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->rsetp(this, p_peer_id, p_unreliable, p_property, p_value); + get_multiplayer()->rpcp(this, p_peer_id, true, p_method, p_arg, p_argcount); } -/******** RSET *********/ -void Node::rset(const StringName &p_property, const Variant &p_value) { - rsetp(0, false, p_property, p_value); -} - -void Node::rset_id(int p_peer_id, const StringName &p_property, const Variant &p_value) { - rsetp(p_peer_id, false, p_property, p_value); -} - -void Node::rset_unreliable(const StringName &p_property, const Variant &p_value) { - rsetp(0, true, p_property, p_value); -} - -void Node::rset_unreliable_id(int p_peer_id, const StringName &p_property, const Variant &p_value) { - rsetp(p_peer_id, true, p_property, p_value); -} - -//////////// end of rpc Ref<MultiplayerAPI> Node::get_multiplayer() const { if (multiplayer.is_valid()) { return multiplayer; @@ -731,99 +616,11 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { multiplayer = p_multiplayer; } -uint16_t Node::get_node_rpc_method_id(const StringName &p_method) const { - for (int i = 0; i < data.rpc_methods.size(); i++) { - if (data.rpc_methods[i].name == p_method) { - // Returns `i` with the high bit set to 1 so we know that this id comes - // from the node and not the script. - return i | (1 << 15); - } - } - return UINT16_MAX; -} - -StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const { - // Make sure this is a node generated ID. - if (((1 << 15) & p_rpc_method_id) > 0) { - int mid = (~(1 << 15)) & p_rpc_method_id; - if (mid < data.rpc_methods.size()) { - return data.rpc_methods[mid].name; - } - } - return StringName(); -} - -MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { - // Make sure this is a node generated ID. - if (((1 << 15) & p_rpc_method_id) > 0) { - int mid = (~(1 << 15)) & p_rpc_method_id; - if (mid < data.rpc_methods.size()) { - return data.rpc_methods[mid].mode; - } - } - return MultiplayerAPI::RPC_MODE_DISABLED; -} - -MultiplayerAPI::RPCMode Node::get_node_rpc_mode(const StringName &p_method) const { - return get_node_rpc_mode_by_id(get_node_rpc_method_id(p_method)); -} - -uint16_t Node::get_node_rset_property_id(const StringName &p_property) const { - for (int i = 0; i < data.rpc_properties.size(); i++) { - if (data.rpc_properties[i].name == p_property) { - // Returns `i` with the high bit set to 1 so we know that this id comes - // from the node and not the script. - return i | (1 << 15); - } - } - return UINT16_MAX; -} - -StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const { - // Make sure this is a node generated ID. - if (((1 << 15) & p_rset_property_id) > 0) { - int mid = (~(1 << 15)) & p_rset_property_id; - if (mid < data.rpc_properties.size()) { - return data.rpc_properties[mid].name; - } - } - return StringName(); +Vector<MultiplayerAPI::RPCConfig> Node::get_node_rpc_methods() const { + return data.rpc_methods; } -MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const { - if (((1 << 15) & p_rset_property_id) > 0) { - int mid = (~(1 << 15)) & p_rset_property_id; - if (mid < data.rpc_properties.size()) { - return data.rpc_properties[mid].mode; - } - } - return MultiplayerAPI::RPC_MODE_DISABLED; -} - -MultiplayerAPI::RPCMode Node::get_node_rset_mode(const StringName &p_property) const { - return get_node_rset_mode_by_id(get_node_rset_property_id(p_property)); -} - -String Node::get_rpc_md5() const { - String rpc_list; - for (int i = 0; i < data.rpc_methods.size(); i += 1) { - rpc_list += String(data.rpc_methods[i].name); - } - for (int i = 0; i < data.rpc_properties.size(); i += 1) { - rpc_list += String(data.rpc_properties[i].name); - } - if (get_script_instance()) { - Vector<ScriptNetData> rpc = get_script_instance()->get_rpc_methods(); - for (int i = 0; i < rpc.size(); i += 1) { - rpc_list += String(rpc[i].name); - } - rpc = get_script_instance()->get_rset_properties(); - for (int i = 0; i < rpc.size(); i += 1) { - rpc_list += String(rpc[i].name); - } - } - return rpc_list.md5_text(); -} +//////////// end of rpc bool Node::can_process_notification(int p_what) const { switch (p_what) { @@ -2776,8 +2573,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer); ClassDB::bind_method(D_METHOD("get_custom_multiplayer"), &Node::get_custom_multiplayer); ClassDB::bind_method(D_METHOD("set_custom_multiplayer", "api"), &Node::set_custom_multiplayer); - ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config); - ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config); + ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description); ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description); @@ -2794,22 +2590,13 @@ void Node::_bind_methods() { mi.name = "rpc"; ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc", &Node::_rpc_bind, mi); - mi.name = "rpc_unreliable"; - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc_unreliable", &Node::_rpc_unreliable_bind, mi); mi.arguments.push_front(PropertyInfo(Variant::INT, "peer_id")); mi.name = "rpc_id"; ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc_id", &Node::_rpc_id_bind, mi); - mi.name = "rpc_unreliable_id"; - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc_unreliable_id", &Node::_rpc_unreliable_id_bind, mi); } - ClassDB::bind_method(D_METHOD("rset", "property", "value"), &Node::rset); - ClassDB::bind_method(D_METHOD("rset_id", "peer_id", "property", "value"), &Node::rset_id); - ClassDB::bind_method(D_METHOD("rset_unreliable", "property", "value"), &Node::rset_unreliable); - ClassDB::bind_method(D_METHOD("rset_unreliable_id", "peer_id", "property", "value"), &Node::rset_unreliable_id); - ClassDB::bind_method(D_METHOD("update_configuration_warnings"), &Node::update_configuration_warnings); BIND_CONSTANT(NOTIFICATION_ENTER_TREE); @@ -2830,6 +2617,9 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE); + BIND_CONSTANT(NOTIFICATION_EDITOR_PRE_SAVE); + BIND_CONSTANT(NOTIFICATION_EDITOR_POST_SAVE); + BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT); BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_IN); diff --git a/scene/main/node.h b/scene/main/node.h index 6ca2317d9e..e7b36f351b 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -80,11 +80,6 @@ private: SceneTree::Group *group = nullptr; }; - struct NetData { - StringName name; - MultiplayerAPI::RPCMode mode = MultiplayerAPI::RPCMode::RPC_MODE_DISABLED; - }; - struct Data { String filename; Ref<SceneState> instance_state; @@ -116,8 +111,7 @@ private: Node *process_owner = nullptr; int network_master = 1; // Server by default. - Vector<NetData> rpc_methods; - Vector<NetData> rpc_properties; + Vector<MultiplayerAPI::RPCConfig> rpc_methods; // Variables used to properly sort the node when processing, ignored otherwise. // TODO: Should move all the stuff below to bits. @@ -179,9 +173,7 @@ private: Array _get_groups() const; Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant _rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant _rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); friend class SceneTree; @@ -253,6 +245,10 @@ public: NOTIFICATION_APPLICATION_FOCUS_IN = MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN, NOTIFICATION_APPLICATION_FOCUS_OUT = MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT, NOTIFICATION_TEXT_SERVER_CHANGED = MainLoop::NOTIFICATION_TEXT_SERVER_CHANGED, + + // Editor specific node notifications + NOTIFICATION_EDITOR_PRE_SAVE = 9001, + NOTIFICATION_EDITOR_POST_SAVE = 9002, }; /* NODE/TREE */ @@ -425,42 +421,17 @@ public: int get_network_master() const; bool is_network_master() const; - uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC - uint16_t rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC + uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, NetworkedMultiplayerPeer::TransferMode p_transfer_mode, int p_channel = 0); // config a local method for RPC + Vector<MultiplayerAPI::RPCConfig> get_node_rpc_methods() const; - void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode - void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode - void rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode - void rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode - - void rset(const StringName &p_property, const Variant &p_value); //remote set call, honors RPCMode - void rset_unreliable(const StringName &p_property, const Variant &p_value); //remote set call, honors RPCMode - void rset_id(int p_peer_id, const StringName &p_property, const Variant &p_value); //remote set call, honors RPCMode - void rset_unreliable_id(int p_peer_id, const StringName &p_property, const Variant &p_value); //remote set call, honors RPCMode - - void rpcp(int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount); - void rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value); + void rpc(const StringName &p_method, VARIANT_ARG_LIST); // RPC, honors RPCMode, TransferMode, channel + void rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); // RPC to specific peer(s), honors RPCMode, TransferMode, channel + void rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); Ref<MultiplayerAPI> get_multiplayer() const; Ref<MultiplayerAPI> get_custom_multiplayer() const; void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer); - /// Returns the rpc method ID, otherwise UINT32_MAX - uint16_t get_node_rpc_method_id(const StringName &p_method) const; - StringName get_node_rpc_method(const uint16_t p_rpc_method_id) const; - MultiplayerAPI::RPCMode get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; - MultiplayerAPI::RPCMode get_node_rpc_mode(const StringName &p_method) const; - - /// Returns the rpc property ID, otherwise UINT32_MAX - uint16_t get_node_rset_property_id(const StringName &p_property) const; - StringName get_node_rset_property(const uint16_t p_rset_property_id) const; - MultiplayerAPI::RPCMode get_node_rset_mode_by_id(const uint16_t p_rpc_method_id) const; - MultiplayerAPI::RPCMode get_node_rset_mode(const StringName &p_property) const; - - /// Can be used to check if the rpc methods and the rset properties are the - /// same across the peers. - String get_rpc_md5() const; - Node(); ~Node(); }; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index cb3b2cb392..3d65c12cb7 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -169,7 +169,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const pinfo.type = Variant::TRANSFORM2D; } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - pinfo.type = Variant::TRANSFORM; + pinfo.type = Variant::TRANSFORM3D; } break; case RS::GLOBAL_VAR_TYPE_MAT4: { pinfo.type = Variant::PACKED_INT32_ARRAY; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 77667cf188..17c0023b09 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -197,8 +197,8 @@ void Viewport::update_worlds() { } void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { - Transform object_transform = p_object->get_global_transform(); - Transform camera_transform = p_camera->get_global_transform(); + Transform3D object_transform = p_object->get_global_transform(); + Transform3D camera_transform = p_camera->get_global_transform(); ObjectID id = p_object->get_instance_id(); //avoid sending the fake event unnecessarily if nothing really changed in the context @@ -553,7 +553,7 @@ void Viewport::_notification(int p_what) { RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); for (int i = 0; i < point_count; i++) { - Transform point_transform; + Transform3D point_transform; point_transform.origin = points[i]; RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform); } @@ -1341,19 +1341,19 @@ bool Viewport::is_camera_override_enabled() const { return camera_override; } -void Viewport::set_camera_override_transform(const Transform &p_transform) { +void Viewport::set_camera_override_transform(const Transform3D &p_transform) { if (camera_override) { camera_override.transform = p_transform; RenderingServer::get_singleton()->camera_set_transform(camera_override.rid, p_transform); } } -Transform Viewport::get_camera_override_transform() const { +Transform3D Viewport::get_camera_override_transform() const { if (camera_override) { return camera_override.transform; } - return Transform(); + return Transform3D(); } void Viewport::set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) { @@ -3669,9 +3669,9 @@ void Viewport::_bind_methods() { 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); + BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_ALBEDO); + BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_LIGHTING); + BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_EMISSION); BIND_ENUM_CONSTANT(DEBUG_DRAW_SHADOW_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index a55df4fbc2..2d7f5101c2 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -130,9 +130,9 @@ public: DEBUG_DRAW_OVERDRAW, DEBUG_DRAW_WIREFRAME, DEBUG_DRAW_NORMAL_BUFFER, - DEBUG_DRAW_GI_PROBE_ALBEDO, - DEBUG_DRAW_GI_PROBE_LIGHTING, - DEBUG_DRAW_GI_PROBE_EMISSION, + DEBUG_DRAW_VOXEL_GI_ALBEDO, + DEBUG_DRAW_VOXEL_GI_LIGHTING, + DEBUG_DRAW_VOXEL_GI_EMISSION, DEBUG_DRAW_SHADOW_ATLAS, DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, DEBUG_DRAW_SCENE_LUMINANCE, @@ -193,7 +193,7 @@ private: Set<Listener3D *> listeners; struct CameraOverrideData { - Transform transform; + Transform3D transform; enum Projection { PROJECTION_PERSPECTIVE, PROJECTION_ORTHOGONAL @@ -254,8 +254,8 @@ private: List<Ref<InputEvent>> physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; - Transform physics_last_object_transform; - Transform physics_last_camera_transform; + Transform3D physics_last_object_transform; + Transform3D physics_last_camera_transform; ObjectID physics_last_id; bool physics_has_last_mousepos = false; Vector2 physics_last_mousepos = Vector2(Math_INF, Math_INF); @@ -493,8 +493,8 @@ public: void enable_camera_override(bool p_enable); bool is_camera_override_enabled() const; - void set_camera_override_transform(const Transform &p_transform); - Transform get_camera_override_transform() const; + void set_camera_override_transform(const Transform3D &p_transform); + Transform3D get_camera_override_transform() const; void set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); void set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index e8ee4cb9fc..332976a18d 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -55,6 +55,7 @@ #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" #include "scene/2d/path_2d.h" +#include "scene/2d/physical_bone_2d.h" #include "scene/2d/physics_body_2d.h" #include "scene/2d/polygon_2d.h" #include "scene/2d/position_2d.h" @@ -65,7 +66,6 @@ #include "scene/2d/tile_map.h" #include "scene/2d/touch_screen_button.h" #include "scene/2d/visibility_notifier_2d.h" -#include "scene/2d/y_sort.h" #include "scene/animation/animation_blend_space_1d.h" #include "scene/animation/animation_blend_space_2d.h" #include "scene/animation/animation_blend_tree.h" @@ -161,6 +161,15 @@ #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/resource_format_text.h" #include "scene/resources/segment_shape_2d.h" +#include "scene/resources/skeleton_modification_2d.h" +#include "scene/resources/skeleton_modification_2d_ccdik.h" +#include "scene/resources/skeleton_modification_2d_fabrik.h" +#include "scene/resources/skeleton_modification_2d_jiggle.h" +#include "scene/resources/skeleton_modification_2d_lookat.h" +#include "scene/resources/skeleton_modification_2d_physicalbones.h" +#include "scene/resources/skeleton_modification_2d_stackholder.h" +#include "scene/resources/skeleton_modification_2d_twoboneik.h" +#include "scene/resources/skeleton_modification_stack_2d.h" #include "scene/resources/sky.h" #include "scene/resources/sky_material.h" #include "scene/resources/sphere_shape_3d.h" @@ -174,33 +183,29 @@ #include "scene/resources/video_stream.h" #include "scene/resources/visual_shader.h" #include "scene/resources/visual_shader_nodes.h" +#include "scene/resources/visual_shader_particle_nodes.h" #include "scene/resources/visual_shader_sdf_nodes.h" #include "scene/resources/world_2d.h" #include "scene/resources/world_3d.h" #include "scene/resources/world_margin_shape_3d.h" #include "scene/scene_string_names.h" -// Needed by animation code, so keep when 3D disabled. -#include "scene/3d/node_3d.h" -#include "scene/3d/skeleton_3d.h" - #include "scene/main/shader_globals_override.h" #ifndef _3D_DISABLED #include "scene/3d/area_3d.h" #include "scene/3d/audio_stream_player_3d.h" -#include "scene/3d/baked_lightmap.h" #include "scene/3d/bone_attachment_3d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" #include "scene/3d/decal.h" -#include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/gpu_particles_collision_3d.h" #include "scene/3d/immediate_geometry_3d.h" #include "scene/3d/light_3d.h" +#include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" #include "scene/3d/listener_3d.h" #include "scene/3d/mesh_instance_3d.h" @@ -208,6 +213,7 @@ #include "scene/3d/navigation_agent_3d.h" #include "scene/3d/navigation_obstacle_3d.h" #include "scene/3d/navigation_region_3d.h" +#include "scene/3d/node_3d.h" #include "scene/3d/occluder_instance_3d.h" #include "scene/3d/path_3d.h" #include "scene/3d/physics_body_3d.h" @@ -217,12 +223,14 @@ #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" #include "scene/3d/remote_transform_3d.h" +#include "scene/3d/skeleton_3d.h" #include "scene/3d/skeleton_ik_3d.h" #include "scene/3d/soft_body_3d.h" #include "scene/3d/spring_arm_3d.h" #include "scene/3d/sprite_3d.h" #include "scene/3d/vehicle_body_3d.h" #include "scene/3d/visibility_notifier_3d.h" +#include "scene/3d/voxel_gi.h" #include "scene/3d/world_environment.h" #include "scene/3d/xr_nodes.h" #include "scene/resources/environment.h" @@ -395,14 +403,7 @@ void register_scene_types() { AcceptDialog::set_swap_cancel_ok(swap_cancel_ok); #endif - /* REGISTER 3D */ - - // Needed even with _3D_DISABLED as used in animation code. - ClassDB::register_class<Node3D>(); - ClassDB::register_virtual_class<Node3DGizmo>(); - ClassDB::register_class<Skin>(); - ClassDB::register_virtual_class<SkinReference>(); - ClassDB::register_class<Skeleton3D>(); + /* REGISTER ANIMATION */ ClassDB::register_class<AnimationPlayer>(); ClassDB::register_class<Tween>(); @@ -432,7 +433,14 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init + /* REGISTER 3D */ + #ifndef _3D_DISABLED + ClassDB::register_class<Node3D>(); + ClassDB::register_virtual_class<Node3DGizmo>(); + ClassDB::register_class<Skin>(); + ClassDB::register_virtual_class<SkinReference>(); + ClassDB::register_class<Skeleton3D>(); ClassDB::register_virtual_class<VisualInstance3D>(); ClassDB::register_virtual_class<GeometryInstance3D>(); ClassDB::register_class<Camera3D>(); @@ -455,10 +463,10 @@ void register_scene_types() { ClassDB::register_class<SpotLight3D>(); ClassDB::register_class<ReflectionProbe>(); ClassDB::register_class<Decal>(); - ClassDB::register_class<GIProbe>(); - ClassDB::register_class<GIProbeData>(); - ClassDB::register_class<BakedLightmap>(); - ClassDB::register_class<BakedLightmapData>(); + ClassDB::register_class<VoxelGI>(); + ClassDB::register_class<VoxelGIData>(); + ClassDB::register_class<LightmapGI>(); + ClassDB::register_class<LightmapGIData>(); ClassDB::register_class<LightmapProbe>(); ClassDB::register_virtual_class<Lightmapper>(); ClassDB::register_class<GPUParticles3D>(); @@ -484,7 +492,7 @@ void register_scene_types() { ClassDB::register_class<StaticBody3D>(); ClassDB::register_class<RigidBody3D>(); ClassDB::register_class<KinematicCollision3D>(); - ClassDB::register_class<KinematicBody3D>(); + ClassDB::register_class<CharacterBody3D>(); ClassDB::register_class<SpringArm3D>(); ClassDB::register_class<PhysicalBone3D>(); @@ -553,6 +561,7 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeVectorFunc>(); ClassDB::register_class<VisualShaderNodeColorFunc>(); ClassDB::register_class<VisualShaderNodeTransformFunc>(); + ClassDB::register_class<VisualShaderNodeUVFunc>(); ClassDB::register_class<VisualShaderNodeDotProduct>(); ClassDB::register_class<VisualShaderNodeVectorLen>(); ClassDB::register_class<VisualShaderNodeDeterminant>(); @@ -605,6 +614,17 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeTextureSDFNormal>(); ClassDB::register_class<VisualShaderNodeSDFRaymarch>(); + ClassDB::register_class<VisualShaderNodeParticleOutput>(); + ClassDB::register_virtual_class<VisualShaderNodeParticleEmitter>(); + ClassDB::register_class<VisualShaderNodeParticleSphereEmitter>(); + ClassDB::register_class<VisualShaderNodeParticleBoxEmitter>(); + ClassDB::register_class<VisualShaderNodeParticleRingEmitter>(); + ClassDB::register_class<VisualShaderNodeParticleMultiplyByAxisAngle>(); + ClassDB::register_class<VisualShaderNodeParticleConeVelocity>(); + ClassDB::register_class<VisualShaderNodeParticleRandomness>(); + ClassDB::register_class<VisualShaderNodeParticleAccelerator>(); + ClassDB::register_class<VisualShaderNodeParticleEmit>(); + ClassDB::register_class<ShaderMaterial>(); ClassDB::register_virtual_class<CanvasItem>(); ClassDB::register_class<CanvasTexture>(); @@ -629,7 +649,7 @@ void register_scene_types() { ClassDB::register_virtual_class<PhysicsBody2D>(); ClassDB::register_class<StaticBody2D>(); ClassDB::register_class<RigidBody2D>(); - ClassDB::register_class<KinematicBody2D>(); + ClassDB::register_class<CharacterBody2D>(); ClassDB::register_class<KinematicCollision2D>(); ClassDB::register_class<Area2D>(); ClassDB::register_class<CollisionShape2D>(); @@ -645,7 +665,6 @@ void register_scene_types() { ClassDB::register_class<DirectionalLight2D>(); ClassDB::register_class<LightOccluder2D>(); ClassDB::register_class<OccluderPolygon2D>(); - ClassDB::register_class<YSort>(); ClassDB::register_class<BackBufferCopy>(); OS::get_singleton()->yield(); //may take time to init @@ -666,6 +685,18 @@ void register_scene_types() { ClassDB::register_class<TouchScreenButton>(); ClassDB::register_class<RemoteTransform2D>(); + ClassDB::register_class<SkeletonModificationStack2D>(); + ClassDB::register_class<SkeletonModification2D>(); + ClassDB::register_class<SkeletonModification2DLookAt>(); + ClassDB::register_class<SkeletonModification2DCCDIK>(); + ClassDB::register_class<SkeletonModification2DFABRIK>(); + ClassDB::register_class<SkeletonModification2DJiggle>(); + ClassDB::register_class<SkeletonModification2DTwoBoneIK>(); + ClassDB::register_class<SkeletonModification2DStackHolder>(); + + ClassDB::register_class<PhysicalBone2D>(); + ClassDB::register_class<SkeletonModification2DPhysicalBones>(); + OS::get_singleton()->yield(); //may take time to init /* REGISTER RESOURCES */ @@ -822,6 +853,11 @@ void register_scene_types() { ClassDB::add_compatibility_class("ToolButton", "Button"); ClassDB::add_compatibility_class("Navigation3D", "Node3D"); ClassDB::add_compatibility_class("Navigation2D", "Node2D"); + ClassDB::add_compatibility_class("YSort", "Node2D"); + ClassDB::add_compatibility_class("GIProbe", "VoxelGI"); + ClassDB::add_compatibility_class("GIProbeData", "VoxelGIData"); + ClassDB::add_compatibility_class("BakedLightmap", "LightmapGI"); + ClassDB::add_compatibility_class("BakedLightmapData", "LightmapGIData"); // Renamed in 4.0. // Keep alphabetical ordering to easily locate classes and avoid duplicates. @@ -867,7 +903,8 @@ void register_scene_types() { ClassDB::add_compatibility_class("HingeJoint", "HingeJoint3D"); ClassDB::add_compatibility_class("ImmediateGeometry", "ImmediateGeometry3D"); ClassDB::add_compatibility_class("Joint", "Joint3D"); - ClassDB::add_compatibility_class("KinematicBody", "KinematicBody3D"); + ClassDB::add_compatibility_class("KinematicBody", "CharacterBody3D"); + ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D"); ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D"); ClassDB::add_compatibility_class("Light", "Light3D"); ClassDB::add_compatibility_class("Listener", "Listener3D"); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 6f64ac6d04..640ec50eb9 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -43,8 +43,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (tracks.size() == track && what == "type") { String type = p_value; - if (type == "transform") { - add_track(TYPE_TRANSFORM); + if (type == "transform" || type == "transform3d") { + add_track(TYPE_TRANSFORM3D); } else if (type == "value") { add_track(TYPE_VALUE); } else if (type == "method") { @@ -75,7 +75,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { } else if (what == "enabled") { track_set_enabled(track, p_value); } else if (what == "keys" || what == "key_values") { - if (track_get_type(track) == TYPE_TRANSFORM) { + if (track_get_type(track) == TYPE_TRANSFORM3D) { TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]); Vector<float> values = p_value; int vcount = values.size(); @@ -318,7 +318,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { ERR_FAIL_INDEX_V(track, tracks.size(), false); if (what == "type") { switch (track_get_type(track)) { - case TYPE_TRANSFORM: + case TYPE_TRANSFORM3D: r_ret = "transform"; break; case TYPE_VALUE: @@ -351,7 +351,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { } else if (what == "enabled") { r_ret = track_is_enabled(track); } else if (what == "keys") { - if (track_get_type(track) == TYPE_TRANSFORM) { + if (track_get_type(track) == TYPE_TRANSFORM3D) { Vector<float> keys; int kk = track_get_key_count(track); keys.resize(kk * 12); @@ -361,7 +361,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { int idx = 0; for (int i = 0; i < track_get_key_count(track); i++) { Vector3 loc; - Quat rot; + Quaternion rot; Vector3 scale; transform_track_get_key(track, i, &loc, &rot, &scale); @@ -590,7 +590,7 @@ int Animation::add_track(TrackType p_type, int p_at_pos) { } switch (p_type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = memnew(TransformTrack); tracks.insert(p_at_pos, tt); } break; @@ -628,7 +628,7 @@ void Animation::remove_track(int p_track) { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); _clear(tt->transforms); @@ -671,7 +671,7 @@ int Animation::get_track_count() const { } Animation::TrackType Animation::track_get_type(int p_track) const { - ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_TRANSFORM); + ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_TRANSFORM3D); return tracks[p_track]->type; } @@ -773,12 +773,12 @@ void Animation::_clear(T &p_keys) { p_keys.clear(); } -Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const { +Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER); Track *t = tracks[p_track]; TransformTrack *tt = static_cast<TransformTrack *>(t); - ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_key, tt->transforms.size(), ERR_INVALID_PARAMETER); if (r_loc) { @@ -794,10 +794,10 @@ Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, return OK; } -int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot, const Vector3 &p_scale) { +int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quaternion &p_rot, const Vector3 &p_scale) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; - ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, -1); + ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, -1); TransformTrack *tt = static_cast<TransformTrack *>(t); @@ -823,7 +823,7 @@ void Animation::track_remove_key(int p_track, int p_idx) { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX(p_idx, tt->transforms.size()); tt->transforms.remove(p_idx); @@ -869,7 +869,7 @@ int Animation::track_find_key(int p_track, float p_time, bool p_exact) const { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); int k = _find(tt->transforms, p_time); if (k < 0 || k >= tt->transforms.size()) { @@ -951,14 +951,14 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { Dictionary d = p_key; Vector3 loc; if (d.has("location")) { loc = d["location"]; } - Quat rot; + Quaternion rot; if (d.has("rotation")) { rot = d["rotation"]; } @@ -1053,7 +1053,7 @@ int Animation::track_get_key_count(int p_track) const { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); return tt->transforms.size(); } break; @@ -1088,7 +1088,7 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), Variant()); @@ -1156,7 +1156,7 @@ float Animation::track_get_key_time(int p_track, int p_key_idx) const { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1); return tt->transforms[p_key_idx].time; @@ -1201,7 +1201,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX(p_key_idx, tt->transforms.size()); TKey<TransformKey> key = tt->transforms[p_key_idx]; @@ -1265,7 +1265,7 @@ float Animation::track_get_key_transition(int p_track, int p_key_idx) const { Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1); return tt->transforms[p_key_idx].transition; @@ -1301,7 +1301,7 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX(p_key_idx, tt->transforms.size()); @@ -1384,7 +1384,7 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra Track *t = tracks[p_track]; switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { TransformTrack *tt = static_cast<TransformTrack *>(t); ERR_FAIL_INDEX(p_key_idx, tt->transforms.size()); tt->transforms.write[p_key_idx].transition = p_transition; @@ -1462,7 +1462,7 @@ Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_ return p_a.lerp(p_b, p_c); } -Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const { +Quaternion Animation::_interpolate(const Quaternion &p_a, const Quaternion &p_b, float p_c) const { return p_a.slerp(p_b, p_c); } @@ -1490,7 +1490,7 @@ Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } -Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const { +Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, float p_c) const { return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c); } @@ -1555,11 +1555,11 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a return a.cubic_interpolate(b, pa, pb, p_c); } - case Variant::QUAT: { - Quat a = p_a; - Quat b = p_b; - Quat pa = p_pre_a; - Quat pb = p_post_b; + case Variant::QUATERNION: { + Quaternion a = p_a; + Quaternion b = p_b; + Quaternion pa = p_pre_a; + Quaternion pb = p_post_b; return a.cubic_slerp(b, pa, pb, p_c); } @@ -1728,10 +1728,10 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola // do a barrel roll } -Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const { +Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER); Track *t = tracks[p_track]; - ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, ERR_INVALID_PARAMETER); TransformTrack *tt = static_cast<TransformTrack *>(t); @@ -1932,7 +1932,7 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float // handle loop by splitting switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { const TransformTrack *tt = static_cast<const TransformTrack *>(t); _track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices); _track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices); @@ -1988,7 +1988,7 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float } switch (t->type) { - case TYPE_TRANSFORM: { + case TYPE_TRANSFORM3D: { const TransformTrack *tt = static_cast<const TransformTrack *>(t); _track_get_key_indices_in_range(tt->transforms, from_time, to_time, p_indices); @@ -2681,7 +2681,7 @@ void Animation::_bind_methods() { ADD_SIGNAL(MethodInfo("tracks_changed")); BIND_ENUM_CONSTANT(TYPE_VALUE); - BIND_ENUM_CONSTANT(TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(TYPE_TRANSFORM3D); BIND_ENUM_CONSTANT(TYPE_METHOD); BIND_ENUM_CONSTANT(TYPE_BEZIER); BIND_ENUM_CONSTANT(TYPE_AUDIO); @@ -2751,9 +2751,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons { //rotation - const Quat &q0 = t0.value.rot; - const Quat &q1 = t1.value.rot; - const Quat &q2 = t2.value.rot; + const Quaternion &q0 = t0.value.rot; + const Quaternion &q1 = t1.value.rot; + const Quaternion &q2 = t2.value.rot; //localize both to rotation from q0 @@ -2763,8 +2763,8 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons } } else { - Quat r02 = (q0.inverse() * q2).normalized(); - Quat r01 = (q0.inverse() * q1).normalized(); + Quaternion r02 = (q0.inverse() * q2).normalized(); + Quaternion r01 = (q0.inverse() * q1).normalized(); Vector3 v02, v01; real_t a02, a01; @@ -2877,7 +2877,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) { ERR_FAIL_INDEX(p_idx, tracks.size()); - ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM); + ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM3D); TransformTrack *tt = static_cast<TransformTrack *>(tracks[p_idx]); bool prev_erased = false; TKey<TransformKey> first_erased; @@ -2917,7 +2917,7 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) { for (int i = 0; i < tracks.size(); i++) { - if (tracks[i]->type == TYPE_TRANSFORM) { + if (tracks[i]->type == TYPE_TRANSFORM3D) { _transform_track_optimize(i, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle); } } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 66bc71c834..1484007333 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -42,7 +42,7 @@ class Animation : public Resource { public: enum TrackType { TYPE_VALUE, ///< Set a value in a property, can be interpolated. - TYPE_TRANSFORM, ///< Transform a node or a bone. + TYPE_TRANSFORM3D, ///< Transform a node or a bone. TYPE_METHOD, ///< Call any method on a specific node. TYPE_BEZIER, ///< Bezier curve TYPE_AUDIO, @@ -88,7 +88,7 @@ private: struct TransformKey { Vector3 loc; - Quat rot; + Quaternion rot; Vector3 scale; }; @@ -97,7 +97,7 @@ private: struct TransformTrack : public Track { Vector<TKey<TransformKey>> transforms; - TransformTrack() { type = TYPE_TRANSFORM; } + TransformTrack() { type = TYPE_TRANSFORM3D; } }; /* PROPERTY VALUE TRACK */ @@ -186,13 +186,13 @@ private: _FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const; _FORCE_INLINE_ Vector3 _interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const; - _FORCE_INLINE_ Quat _interpolate(const Quat &p_a, const Quat &p_b, float p_c) const; + _FORCE_INLINE_ Quaternion _interpolate(const Quaternion &p_a, const Quaternion &p_b, float p_c) const; _FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, float p_c) const; _FORCE_INLINE_ float _interpolate(const float &p_a, const float &p_b, float p_c) const; _FORCE_INLINE_ Animation::TransformKey _cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const; _FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const; - _FORCE_INLINE_ Quat _cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const; + _FORCE_INLINE_ Quaternion _cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, float p_c) const; _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const; _FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const; @@ -213,7 +213,7 @@ private: private: Array _transform_track_interpolate(int p_track, float p_time) const { Vector3 loc; - Quat rot; + Quaternion rot; Vector3 scale; transform_track_interpolate(p_track, p_time, &loc, &rot, &scale); Array ret; @@ -291,8 +291,8 @@ public: float track_get_key_time(int p_track, int p_key_idx) const; float track_get_key_transition(int p_track, int p_key_idx) const; - int transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3()); - Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const; + int transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quaternion &p_rot = Quaternion(), const Vector3 &p_scale = Vector3()); + Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; void track_set_interpolation_type(int p_track, InterpolationType p_interp); InterpolationType track_get_interpolation_type(int p_track) const; @@ -321,7 +321,7 @@ public: void track_set_interpolation_loop_wrap(int p_track, bool p_enable); bool track_get_interpolation_loop_wrap(int p_track) const; - Error transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const; + Error transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; Variant value_track_interpolate(int p_track, float p_time) const; void value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 100fccc783..2c5634e6ef 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -505,9 +505,6 @@ void BaseMaterial3D::_update_shader() { case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break; - case DIFFUSE_OREN_NAYAR: - code += ",diffuse_oren_nayar"; - break; case DIFFUSE_TOON: code += ",diffuse_toon"; break; @@ -891,7 +888,7 @@ void BaseMaterial3D::_update_shader() { code += "\t\tfloat current_layer_depth = 0.0;\n"; code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n"; code += "\t\tvec2 delta = P / num_layers;\n"; - code += "\t\tvec2 ofs = base_uv;\n"; + code += "\t\tvec2 ofs = base_uv;\n"; if (flags[FLAG_INVERT_HEIGHTMAP]) { code += "\t\tfloat depth = texture(texture_heightmap, ofs).r;\n"; } else { @@ -2400,7 +2397,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Shading", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex"), "set_shading_mode", "get_shading_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Toon"), "set_diffuse_mode", "get_diffuse_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); @@ -2654,7 +2651,6 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT); BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT_WRAP); - BIND_ENUM_CONSTANT(DIFFUSE_OREN_NAYAR); BIND_ENUM_CONSTANT(DIFFUSE_TOON); BIND_ENUM_CONSTANT(SPECULAR_SCHLICK_GGX); diff --git a/scene/resources/material.h b/scene/resources/material.h index ad1b7b3e33..dc3ecdb5de 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -243,7 +243,6 @@ public: DIFFUSE_BURLEY, DIFFUSE_LAMBERT, DIFFUSE_LAMBERT_WRAP, - DIFFUSE_OREN_NAYAR, DIFFUSE_TOON, DIFFUSE_MAX }; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 33ad15b938..5e8e77c730 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -582,8 +582,9 @@ Vector<Ref<Shape3D>> Mesh::convex_decompose() const { int Mesh::get_builtin_bind_pose_count() const { return 0; } -Transform Mesh::get_builtin_bind_pose(int p_index) const { - return Transform(); + +Transform3D Mesh::get_builtin_bind_pose(int p_index) const { + return Transform3D(); } Mesh::Mesh() { @@ -1410,12 +1411,12 @@ struct ArrayMeshLightmapSurface { uint32_t format = 0; }; -Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { +Error ArrayMesh::lightmap_unwrap(const Transform3D &p_base_transform, float p_texel_size) { Vector<uint8_t> null_cache; return lightmap_unwrap_cached(p_base_transform, p_texel_size, null_cache, null_cache, false); } -Error ArrayMesh::lightmap_unwrap_cached(const Transform &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache) { +Error ArrayMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache) { 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."); @@ -1431,7 +1432,7 @@ Error ArrayMesh::lightmap_unwrap_cached(const Transform &p_base_transform, float Basis basis = p_base_transform.get_basis(); Vector3 scale = Vector3(basis.get_axis(0).length(), basis.get_axis(1).length(), basis.get_axis(2).length()); - Transform transform; + Transform3D transform; transform.scale(scale); Basis normal_basis = transform.basis.inverse().transposed(); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index aa830d7b50..2dfb46782b 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -166,7 +166,7 @@ public: Vector<Ref<Shape3D>> convex_decompose() const; virtual int get_builtin_bind_pose_count() const; - virtual Transform get_builtin_bind_pose(int p_index) const; + virtual Transform3D get_builtin_bind_pose(int p_index) const; Mesh(); }; @@ -262,8 +262,8 @@ public: void regen_normal_maps(); - Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); - Error lightmap_unwrap_cached(const Transform &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache = true); + Error lightmap_unwrap(const Transform3D &p_base_transform = Transform3D(), float p_texel_size = 0.05); + Error lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache = true); virtual void reload_from_file() override; diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index ad90481fbd..33c9ca6d1e 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -97,10 +97,10 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const { String name = "item/" + itos(E->key()) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, name + "name")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "mesh_transform")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, name + "mesh_transform")); p_list->push_back(PropertyInfo(Variant::ARRAY, name + "shapes")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh")); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "navmesh_transform")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, name + "navmesh_transform")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER)); } } @@ -145,7 +145,7 @@ void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navm notify_property_list_changed(); } -void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) { +void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform3D &p_transform) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].navmesh_transform = p_transform; notify_change_to_owners(); @@ -180,8 +180,8 @@ Ref<NavigationMesh> MeshLibrary::get_item_navmesh(int p_item) const { return item_map[p_item].navmesh; } -Transform MeshLibrary::get_item_navmesh_transform(int p_item) const { - ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Transform(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); +Transform3D MeshLibrary::get_item_navmesh_transform(int p_item) const { + ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Transform3D(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); return item_map[p_item].navmesh_transform; } diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 1da624c275..1e8a6bf3ff 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -44,14 +44,14 @@ class MeshLibrary : public Resource { public: struct ShapeData { Ref<Shape3D> shape; - Transform local_transform; + Transform3D local_transform; }; struct Item { String name; Ref<Mesh> mesh; Vector<ShapeData> shapes; Ref<Texture2D> preview; - Transform navmesh_transform; + Transform3D navmesh_transform; Ref<NavigationMesh> navmesh; }; @@ -73,13 +73,13 @@ public: void set_item_name(int p_item, const String &p_name); void set_item_mesh(int p_item, const Ref<Mesh> &p_mesh); void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh); - void set_item_navmesh_transform(int p_item, const Transform &p_transform); + void set_item_navmesh_transform(int p_item, const Transform3D &p_transform); void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes); void set_item_preview(int p_item, const Ref<Texture2D> &p_preview); String get_item_name(int p_item) const; Ref<Mesh> get_item_mesh(int p_item) const; Ref<NavigationMesh> get_item_navmesh(int p_item) const; - Transform get_item_navmesh_transform(int p_item) const; + Transform3D get_item_navmesh_transform(int p_item) const; Vector<ShapeData> get_item_shapes(int p_item) const; Ref<Texture2D> get_item_preview(int p_item) const; diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 4991887eb3..dea5c4e7d3 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -50,7 +50,7 @@ void MultiMesh::_set_transform_array(const Vector<Vector3> &p_array) { const Vector3 *r = xforms.ptr(); for (int i = 0; i < len / 4; i++) { - Transform t; + Transform3D t; t.basis[0] = r[i * 4 + 0]; t.basis[1] = r[i * 4 + 1]; t.basis[2] = r[i * 4 + 2]; @@ -75,7 +75,7 @@ Vector<Vector3> MultiMesh::_get_transform_array() const { Vector3 *w = xforms.ptrw(); for (int i = 0; i < instance_count; i++) { - Transform t = get_instance_transform(i); + Transform3D t = get_instance_transform(i); w[i * 4 + 0] = t.basis[0]; w[i * 4 + 1] = t.basis[1]; w[i * 4 + 2] = t.basis[2]; @@ -236,7 +236,7 @@ int MultiMesh::get_visible_instance_count() const { return visible_instance_count; } -void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transform) { +void MultiMesh::set_instance_transform(int p_instance, const Transform3D &p_transform) { RenderingServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform); } @@ -244,7 +244,7 @@ void MultiMesh::set_instance_transform_2d(int p_instance, const Transform2D &p_t RenderingServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform); } -Transform MultiMesh::get_instance_transform(int p_instance) const { +Transform3D MultiMesh::get_instance_transform(int p_instance) const { return RenderingServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance); } diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index ca5c42d47a..2fe0927e6f 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -92,9 +92,9 @@ public: void set_visible_instance_count(int p_count); int get_visible_instance_count() const; - void set_instance_transform(int p_instance, const Transform &p_transform); + void set_instance_transform(int p_instance, const Transform3D &p_transform); void set_instance_transform_2d(int p_instance, const Transform2D &p_transform); - Transform get_instance_transform(int p_instance) const; + Transform3D get_instance_transform(int p_instance) const; Transform2D get_instance_transform_2d(int p_instance) const; void set_instance_color(int p_instance, const Color &p_color); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 64b43f82c6..a745df522b 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1607,10 +1607,10 @@ int TubeTrailMesh::get_builtin_bind_pose_count() const { return sections + 1; } -Transform TubeTrailMesh::get_builtin_bind_pose(int p_index) const { +Transform3D TubeTrailMesh::get_builtin_bind_pose(int p_index) const { float depth = section_length * sections; - Transform xform; + Transform3D xform; xform.origin.y = depth / 2.0 - section_length * float(p_index); xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y @@ -1931,10 +1931,10 @@ int RibbonTrailMesh::get_builtin_bind_pose_count() const { return sections + 1; } -Transform RibbonTrailMesh::get_builtin_bind_pose(int p_index) const { +Transform3D RibbonTrailMesh::get_builtin_bind_pose(int p_index) const { float depth = section_length * sections; - Transform xform; + Transform3D xform; xform.origin.y = depth / 2.0 - section_length * float(p_index); xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index ec5806489e..bd6f94921e 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -374,7 +374,7 @@ public: Ref<Curve> get_curve() const; virtual int get_builtin_bind_pose_count() const override; - virtual Transform get_builtin_bind_pose(int p_index) const override; + virtual Transform3D get_builtin_bind_pose(int p_index) const override; TubeTrailMesh(); }; @@ -424,7 +424,7 @@ public: Ref<Curve> get_curve() const; virtual int get_builtin_bind_pose_count() const override; - virtual Transform get_builtin_bind_pose(int p_index) const override; + virtual Transform3D get_builtin_bind_pose(int p_index) const override; RibbonTrailMesh(); }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 77c6199794..0ad21b0f0f 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -184,7 +184,7 @@ RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_origi } void ResourceFormatLoaderShader::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("shader"); + p_extensions->push_back("gdshader"); } bool ResourceFormatLoaderShader::handles_type(const String &p_type) const { @@ -193,7 +193,7 @@ bool ResourceFormatLoaderShader::handles_type(const String &p_type) const { String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const { String el = p_path.get_extension().to_lower(); - if (el == "shader") { + if (el == "gdshader") { return "Shader"; } return ""; @@ -224,7 +224,7 @@ Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resourc void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { if (const Shader *shader = Object::cast_to<Shader>(*p_resource)) { if (shader->is_text_shader()) { - p_extensions->push_back("shader"); + p_extensions->push_back("gdshader"); } } } diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp index cb44e059a3..a02a0e5488 100644 --- a/scene/resources/shape_3d.cpp +++ b/scene/resources/shape_3d.cpp @@ -35,7 +35,7 @@ #include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" -void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform) { +void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform3D &p_xform) { Vector<Vector3> toadd = get_debug_mesh_lines(); if (toadd.size()) { diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index 0644940fd4..b8e529cd3c 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -60,7 +60,7 @@ public: /// Returns the radius of a sphere that fully enclose this shape virtual real_t get_enclosing_radius() const = 0; - void add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform); + void add_vertices_to_array(Vector<Vector3> &array, const Transform3D &p_xform); real_t get_margin() const; void set_margin(real_t p_margin); diff --git a/scene/resources/skeleton_modification_2d.cpp b/scene/resources/skeleton_modification_2d.cpp new file mode 100644 index 0000000000..9b07293965 --- /dev/null +++ b/scene/resources/skeleton_modification_2d.cpp @@ -0,0 +1,251 @@ +/*************************************************************************/ +/* skeleton_modification_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d.h" +#include "scene/2d/skeleton_2d.h" + +#include "scene/2d/collision_object_2d.h" +#include "scene/2d/collision_shape_2d.h" +#include "scene/2d/physical_bone_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif // TOOLS_ENABLED + +/////////////////////////////////////// +// Modification2D +/////////////////////////////////////// + +void SkeletonModification2D::_execute(float p_delta) { + call("_execute", p_delta); + + if (!enabled) { + return; + } +} + +void SkeletonModification2D::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + if (stack) { + is_setup = true; + } else { + WARN_PRINT("Could not setup modification with name " + get_name()); + } + + call("_setup_modification", p_stack); +} + +void SkeletonModification2D::_draw_editor_gizmo() { + call("_draw_editor_gizmo"); +} + +void SkeletonModification2D::set_enabled(bool p_enabled) { + enabled = p_enabled; + +#ifdef TOOLS_ENABLED + if (editor_draw_gizmo) { + if (stack) { + stack->set_editor_gizmos_dirty(true); + } + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2D::get_enabled() { + return enabled; +} + +float SkeletonModification2D::clamp_angle(float p_angle, float p_min_bound, float p_max_bound, bool p_invert) { + // Map to the 0 to 360 range (in radians though) instead of the -180 to 180 range. + if (p_angle < 0) { + p_angle = Math_TAU + p_angle; + } + + // Make min and max in the range of 0 to 360 (in radians), and make sure they are in the right order + if (p_min_bound < 0) { + p_min_bound = Math_TAU + p_min_bound; + } + if (p_max_bound < 0) { + p_max_bound = Math_TAU + p_max_bound; + } + if (p_min_bound > p_max_bound) { + float tmp = p_min_bound; + p_min_bound = p_max_bound; + p_max_bound = tmp; + } + + // Note: May not be the most optimal way to clamp, but it always constraints to the nearest angle. + if (p_invert == false) { + if (p_angle < p_min_bound || p_angle > p_max_bound) { + Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound)); + Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound)); + Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle)); + + if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) { + p_angle = p_min_bound; + } else { + p_angle = p_max_bound; + } + } + } else { + if (p_angle > p_min_bound && p_angle < p_max_bound) { + Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound)); + Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound)); + Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle)); + + if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) { + p_angle = p_min_bound; + } else { + p_angle = p_max_bound; + } + } + } + return p_angle; +} + +void SkeletonModification2D::editor_draw_angle_constraints(Bone2D *p_operation_bone, float p_min_bound, float p_max_bound, + bool p_constraint_enabled, bool p_constraint_in_localspace, bool p_constraint_inverted) { + if (!p_operation_bone) { + return; + } + + Color bone_ik_color = Color(1.0, 0.65, 0.0, 0.4); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); + } +#endif // TOOLS_ENABLED + + float arc_angle_min = p_min_bound; + float arc_angle_max = p_max_bound; + if (arc_angle_min < 0) { + arc_angle_min = (Math_PI * 2) + arc_angle_min; + } + if (arc_angle_max < 0) { + arc_angle_max = (Math_PI * 2) + arc_angle_max; + } + if (arc_angle_min > arc_angle_max) { + float tmp = arc_angle_min; + arc_angle_min = arc_angle_max; + arc_angle_max = tmp; + } + arc_angle_min += p_operation_bone->get_bone_angle(); + arc_angle_max += p_operation_bone->get_bone_angle(); + + if (p_constraint_enabled) { + if (p_constraint_in_localspace) { + Node *operation_bone_parent = p_operation_bone->get_parent(); + Bone2D *operation_bone_parent_bone = Object::cast_to<Bone2D>(operation_bone_parent); + + if (operation_bone_parent_bone) { + stack->skeleton->draw_set_transform( + stack->skeleton->get_global_transform().affine_inverse().xform(p_operation_bone->get_global_position()), + operation_bone_parent_bone->get_global_rotation() - stack->skeleton->get_global_rotation()); + } else { + stack->skeleton->draw_set_transform(stack->skeleton->get_global_transform().affine_inverse().xform(p_operation_bone->get_global_position())); + } + } else { + stack->skeleton->draw_set_transform(stack->skeleton->get_global_transform().affine_inverse().xform(p_operation_bone->get_global_position())); + } + + if (p_constraint_inverted) { + stack->skeleton->draw_arc(Vector2(0, 0), p_operation_bone->get_length(), + arc_angle_min + (Math_PI * 2), arc_angle_max, 32, bone_ik_color, 1.0); + } else { + stack->skeleton->draw_arc(Vector2(0, 0), p_operation_bone->get_length(), + arc_angle_min, arc_angle_max, 32, bone_ik_color, 1.0); + } + stack->skeleton->draw_line(Vector2(0, 0), Vector2(Math::cos(arc_angle_min), Math::sin(arc_angle_min)) * p_operation_bone->get_length(), bone_ik_color, 1.0); + stack->skeleton->draw_line(Vector2(0, 0), Vector2(Math::cos(arc_angle_max), Math::sin(arc_angle_max)) * p_operation_bone->get_length(), bone_ik_color, 1.0); + + } else { + stack->skeleton->draw_set_transform(stack->skeleton->get_global_transform().affine_inverse().xform(p_operation_bone->get_global_position())); + stack->skeleton->draw_arc(Vector2(0, 0), p_operation_bone->get_length(), 0, Math_PI * 2, 32, bone_ik_color, 1.0); + stack->skeleton->draw_line(Vector2(0, 0), Vector2(1, 0) * p_operation_bone->get_length(), bone_ik_color, 1.0); + } +} + +Ref<SkeletonModificationStack2D> SkeletonModification2D::get_modification_stack() { + return stack; +} + +void SkeletonModification2D::set_is_setup(bool p_setup) { + is_setup = p_setup; +} + +bool SkeletonModification2D::get_is_setup() const { + return is_setup; +} + +void SkeletonModification2D::set_execution_mode(int p_mode) { + execution_mode = p_mode; +} + +int SkeletonModification2D::get_execution_mode() const { + return execution_mode; +} + +void SkeletonModification2D::set_editor_draw_gizmo(bool p_draw_gizmo) { + editor_draw_gizmo = p_draw_gizmo; +#ifdef TOOLS_ENABLED + if (is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2D::get_editor_draw_gizmo() const { + return editor_draw_gizmo; +} + +void SkeletonModification2D::_bind_methods() { + BIND_VMETHOD(MethodInfo("_execute", PropertyInfo(Variant::FLOAT, "delta"))); + BIND_VMETHOD(MethodInfo("_setup_modification", PropertyInfo(Variant::OBJECT, "modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D"))); + BIND_VMETHOD(MethodInfo("_draw_editor_gizmo")); + + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &SkeletonModification2D::set_enabled); + ClassDB::bind_method(D_METHOD("get_enabled"), &SkeletonModification2D::get_enabled); + ClassDB::bind_method(D_METHOD("get_modification_stack"), &SkeletonModification2D::get_modification_stack); + ClassDB::bind_method(D_METHOD("set_is_setup", "is_setup"), &SkeletonModification2D::set_is_setup); + ClassDB::bind_method(D_METHOD("get_is_setup"), &SkeletonModification2D::get_is_setup); + ClassDB::bind_method(D_METHOD("set_execution_mode", "execution_mode"), &SkeletonModification2D::set_execution_mode); + ClassDB::bind_method(D_METHOD("get_execution_mode"), &SkeletonModification2D::get_execution_mode); + ClassDB::bind_method(D_METHOD("clamp_angle", "angle", "min", "max", "invert"), &SkeletonModification2D::clamp_angle); + ClassDB::bind_method(D_METHOD("set_editor_draw_gizmo", "draw_gizmo"), &SkeletonModification2D::set_editor_draw_gizmo); + ClassDB::bind_method(D_METHOD("get_editor_draw_gizmo"), &SkeletonModification2D::get_editor_draw_gizmo); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "execution_mode", PROPERTY_HINT_ENUM, "process, physics_process"), "set_execution_mode", "get_execution_mode"); +} + +SkeletonModification2D::SkeletonModification2D() { + stack = nullptr; + is_setup = false; +} diff --git a/scene/resources/skeleton_modification_2d.h b/scene/resources/skeleton_modification_2d.h new file mode 100644 index 0000000000..18633e55cb --- /dev/null +++ b/scene/resources/skeleton_modification_2d.h @@ -0,0 +1,85 @@ +/*************************************************************************/ +/* skeleton_modification_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2D_H +#define SKELETONMODIFICATION2D_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_stack_2d.h" + +/////////////////////////////////////// +// SkeletonModification2D +/////////////////////////////////////// + +class SkeletonModificationStack2D; +class Bone2D; + +class SkeletonModification2D : public Resource { + GDCLASS(SkeletonModification2D, Resource); + friend class Skeleton2D; + friend class Bone2D; + +protected: + static void _bind_methods(); + + SkeletonModificationStack2D *stack; + int execution_mode = 0; // 0 = process + + bool enabled = true; + bool is_setup = false; + + bool _print_execution_error(bool p_condition, String p_message); + +public: + virtual void _execute(float _delta); + virtual void _setup_modification(SkeletonModificationStack2D *p_stack); + virtual void _draw_editor_gizmo(); + + bool editor_draw_gizmo = false; + void set_editor_draw_gizmo(bool p_draw_gizmo); + bool get_editor_draw_gizmo() const; + + void set_enabled(bool p_enabled); + bool get_enabled(); + + Ref<SkeletonModificationStack2D> get_modification_stack(); + void set_is_setup(bool p_setup); + bool get_is_setup() const; + + void set_execution_mode(int p_mode); + int get_execution_mode() const; + + float clamp_angle(float p_angle, float p_min_bound, float p_max_bound, bool p_invert_clamp = false); + void editor_draw_angle_constraints(Bone2D *p_operation_bone, float p_min_bound, float p_max_bound, bool p_constraint_enabled, bool p_constraint_in_localspace, bool p_constraint_inverted); + + SkeletonModification2D(); +}; + +#endif // SKELETONMODIFICATION2D_H diff --git a/scene/resources/skeleton_modification_2d_ccdik.cpp b/scene/resources/skeleton_modification_2d_ccdik.cpp new file mode 100644 index 0000000000..7ea60e584e --- /dev/null +++ b/scene/resources/skeleton_modification_2d_ccdik.cpp @@ -0,0 +1,545 @@ +/*************************************************************************/ +/* skeleton_modification_2d_ccdik.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_ccdik.h" +#include "scene/2d/skeleton_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif // TOOLS_ENABLED + +bool SkeletonModification2DCCDIK::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, ccdik_data_chain.size(), false); + + if (what == "bone2d_node") { + set_ccdik_joint_bone2d_node(which, p_value); + } else if (what == "bone_index") { + set_ccdik_joint_bone_index(which, p_value); + } else if (what == "rotate_from_joint") { + set_ccdik_joint_rotate_from_joint(which, p_value); + } else if (what == "enable_constraint") { + set_ccdik_joint_enable_constraint(which, p_value); + } else if (what == "constraint_angle_min") { + set_ccdik_joint_constraint_angle_min(which, Math::deg2rad(float(p_value))); + } else if (what == "constraint_angle_max") { + set_ccdik_joint_constraint_angle_max(which, Math::deg2rad(float(p_value))); + } else if (what == "constraint_angle_invert") { + set_ccdik_joint_constraint_angle_invert(which, p_value); + } else if (what == "constraint_in_localspace") { + set_ccdik_joint_constraint_in_localspace(which, p_value); + } + +#ifdef TOOLS_ENABLED + if (what.begins_with("editor_draw_gizmo")) { + set_ccdik_joint_editor_draw_gizmo(which, p_value); + } +#endif // TOOLS_ENABLED + + return true; + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + set_editor_draw_gizmo(p_value); + } +#endif // TOOLS_ENABLED + + return true; +} + +bool SkeletonModification2DCCDIK::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, ccdik_data_chain.size(), false); + + if (what == "bone2d_node") { + r_ret = get_ccdik_joint_bone2d_node(which); + } else if (what == "bone_index") { + r_ret = get_ccdik_joint_bone_index(which); + } else if (what == "rotate_from_joint") { + r_ret = get_ccdik_joint_rotate_from_joint(which); + } else if (what == "enable_constraint") { + r_ret = get_ccdik_joint_enable_constraint(which); + } else if (what == "constraint_angle_min") { + r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_min(which)); + } else if (what == "constraint_angle_max") { + r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_max(which)); + } else if (what == "constraint_angle_invert") { + r_ret = get_ccdik_joint_constraint_angle_invert(which); + } else if (what == "constraint_in_localspace") { + r_ret = get_ccdik_joint_constraint_in_localspace(which); + } + +#ifdef TOOLS_ENABLED + if (what.begins_with("editor_draw_gizmo")) { + r_ret = get_ccdik_joint_editor_draw_gizmo(which); + } +#endif // TOOLS_ENABLED + + return true; + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + r_ret = get_editor_draw_gizmo(); + } +#endif // TOOLS_ENABLED + + return true; +} + +void SkeletonModification2DCCDIK::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < ccdik_data_chain.size(); i++) { + String base_string = "joint_data/" + itos(i) + "/"; + + p_list->push_back(PropertyInfo(Variant::INT, base_string + "bone_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::NODE_PATH, base_string + "bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "rotate_from_joint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "enable_constraint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (ccdik_data_chain[i].enable_constraint) { + p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "constraint_angle_min", PROPERTY_HINT_RANGE, "-360, 360, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "constraint_angle_max", PROPERTY_HINT_RANGE, "-360, 360, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "constraint_angle_invert", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "constraint_in_localspace", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "editor_draw_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif // TOOLS_ENABLED + } + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, "editor/draw_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif // TOOLS_ENABLED +} + +void SkeletonModification2DCCDIK::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + + if (target_node_cache.is_null()) { + WARN_PRINT_ONCE("Target cache is out of date. Attempting to update..."); + update_target_cache(); + return; + } + if (tip_node_cache.is_null()) { + WARN_PRINT_ONCE("Tip cache is out of date. Attempting to update..."); + update_tip_cache(); + return; + } + + Node2D *target = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + if (!target || !target->is_inside_tree()) { + ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!"); + return; + } + + Node2D *tip = Object::cast_to<Node2D>(ObjectDB::get_instance(tip_node_cache)); + if (!tip || !tip->is_inside_tree()) { + ERR_PRINT_ONCE("Tip node is not in the scene tree. Cannot execute modification!"); + return; + } + + for (int i = 0; i < ccdik_data_chain.size(); i++) { + _execute_ccdik_joint(i, target, tip); + } +} + +void SkeletonModification2DCCDIK::_execute_ccdik_joint(int p_joint_idx, Node2D *p_target, Node2D *p_tip) { + CCDIK_Joint_Data2D ccdik_data = ccdik_data_chain[p_joint_idx]; + if (ccdik_data.bone_idx < 0 || ccdik_data.bone_idx > stack->skeleton->get_bone_count()) { + ERR_PRINT_ONCE("2D CCDIK joint: bone index not found!"); + return; + } + + Bone2D *operation_bone = stack->skeleton->get_bone(ccdik_data.bone_idx); + Transform2D operation_transform = operation_bone->get_global_transform(); + + if (ccdik_data.rotate_from_joint) { + // To rotate from the joint, simply look at the target! + operation_transform.set_rotation( + operation_transform.looking_at(p_target->get_global_transform().get_origin()).get_rotation() - operation_bone->get_bone_angle()); + } else { + // How to rotate from the tip: get the difference of rotation needed from the tip to the target, from the perspective of the joint. + // Because we are only using the offset, we do not need to account for the bone angle of the Bone2D node. + float joint_to_tip = operation_transform.get_origin().angle_to_point(p_tip->get_global_transform().get_origin()); + float joint_to_target = operation_transform.get_origin().angle_to_point(p_target->get_global_transform().get_origin()); + operation_transform.set_rotation( + operation_transform.get_rotation() + (joint_to_target - joint_to_tip)); + } + + // Reset scale + operation_transform.set_scale(operation_bone->get_global_transform().get_scale()); + + // Apply constraints in globalspace: + if (ccdik_data.enable_constraint && !ccdik_data.constraint_in_localspace) { + operation_transform.set_rotation(clamp_angle(operation_transform.get_rotation(), ccdik_data.constraint_angle_min, ccdik_data.constraint_angle_max, ccdik_data.constraint_angle_invert)); + } + + // Convert from a global transform to a delta and then apply the delta to the local transform. + operation_bone->set_global_transform(operation_transform); + operation_transform = operation_bone->get_transform(); + + // Apply constraints in localspace: + if (ccdik_data.enable_constraint && ccdik_data.constraint_in_localspace) { + operation_transform.set_rotation(clamp_angle(operation_transform.get_rotation(), ccdik_data.constraint_angle_min, ccdik_data.constraint_angle_max, ccdik_data.constraint_angle_invert)); + } + + // Set the local pose override, and to make sure child bones are also updated, set the transform of the bone. + stack->skeleton->set_bone_local_pose_override(ccdik_data.bone_idx, operation_transform, stack->strength, true); + operation_bone->set_transform(operation_transform); + operation_bone->notification(operation_bone->NOTIFICATION_TRANSFORM_CHANGED); +} + +void SkeletonModification2DCCDIK::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack != nullptr) { + is_setup = true; + update_target_cache(); + update_tip_cache(); + } +} + +void SkeletonModification2DCCDIK::_draw_editor_gizmo() { + if (!enabled || !is_setup) { + return; + } + + for (int i = 0; i < ccdik_data_chain.size(); i++) { + if (!ccdik_data_chain[i].editor_draw_gizmo) { + continue; + } + + Bone2D *operation_bone = stack->skeleton->get_bone(ccdik_data_chain[i].bone_idx); + editor_draw_angle_constraints(operation_bone, ccdik_data_chain[i].constraint_angle_min, ccdik_data_chain[i].constraint_angle_max, + ccdik_data_chain[i].enable_constraint, ccdik_data_chain[i].constraint_in_localspace, ccdik_data_chain[i].constraint_angle_invert); + } +} + +void SkeletonModification2DCCDIK::update_target_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + return; + } + + target_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(target_node)) { + Node *node = stack->skeleton->get_node(target_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update target cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update target cache: node is not in the scene tree!"); + target_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DCCDIK::update_tip_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update tip cache: modification is not properly setup!"); + return; + } + + tip_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(tip_node)) { + Node *node = stack->skeleton->get_node(tip_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update tip cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update tip cache: node is not in the scene tree!"); + tip_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DCCDIK::ccdik_joint_update_bone2d_cache(int p_joint_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update CCDIK Bone2D cache: modification is not properly setup!"); + return; + } + + ccdik_data_chain.write[p_joint_idx].bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(ccdik_data_chain[p_joint_idx].bone2d_node)) { + Node *node = stack->skeleton->get_node(ccdik_data_chain[p_joint_idx].bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update CCDIK joint " + itos(p_joint_idx) + " Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update CCDIK joint " + itos(p_joint_idx) + " Bone2D cache: node is not in the scene tree!"); + ccdik_data_chain.write[p_joint_idx].bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + ccdik_data_chain.write[p_joint_idx].bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("CCDIK joint " + itos(p_joint_idx) + " Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + } + } + } +} + +void SkeletonModification2DCCDIK::set_target_node(const NodePath &p_target_node) { + target_node = p_target_node; + update_target_cache(); +} + +NodePath SkeletonModification2DCCDIK::get_target_node() const { + return target_node; +} + +void SkeletonModification2DCCDIK::set_tip_node(const NodePath &p_tip_node) { + tip_node = p_tip_node; + update_tip_cache(); +} + +NodePath SkeletonModification2DCCDIK::get_tip_node() const { + return tip_node; +} + +void SkeletonModification2DCCDIK::set_ccdik_data_chain_length(int p_length) { + ccdik_data_chain.resize(p_length); + notify_property_list_changed(); +} + +int SkeletonModification2DCCDIK::get_ccdik_data_chain_length() { + return ccdik_data_chain.size(); +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].bone2d_node = p_target_node; + ccdik_joint_update_bone2d_cache(p_joint_idx); + + notify_property_list_changed(); +} + +NodePath SkeletonModification2DCCDIK::get_ccdik_joint_bone2d_node(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), NodePath(), "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].bone2d_node; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_bone_index(int p_joint_idx, int p_bone_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCCDIK joint out of range!"); + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + ccdik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + ccdik_data_chain.write[p_joint_idx].bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + ccdik_data_chain.write[p_joint_idx].bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("Cannot verify the CCDIK joint " + itos(p_joint_idx) + " bone index for this modification..."); + ccdik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("Cannot verify the CCDIK joint " + itos(p_joint_idx) + " bone index for this modification..."); + ccdik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +int SkeletonModification2DCCDIK::get_ccdik_joint_bone_index(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), -1, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].bone_idx; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_rotate_from_joint(int p_joint_idx, bool p_rotate_from_joint) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].rotate_from_joint = p_rotate_from_joint; +} + +bool SkeletonModification2DCCDIK::get_ccdik_joint_rotate_from_joint(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), false, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].rotate_from_joint; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_enable_constraint(int p_joint_idx, bool p_constraint) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].enable_constraint = p_constraint; + notify_property_list_changed(); + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DCCDIK::get_ccdik_joint_enable_constraint(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), false, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].enable_constraint; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_min(int p_joint_idx, float p_angle_min) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].constraint_angle_min = p_angle_min; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +float SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_min(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), 0.0, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].constraint_angle_min; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_max(int p_joint_idx, float p_angle_max) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].constraint_angle_max = p_angle_max; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +float SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_max(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), 0.0, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].constraint_angle_max; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_invert(int p_joint_idx, bool p_invert) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].constraint_angle_invert = p_invert; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_invert(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), false, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].constraint_angle_invert; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_constraint_in_localspace(int p_joint_idx, bool p_constraint_in_localspace) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].constraint_in_localspace = p_constraint_in_localspace; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DCCDIK::get_ccdik_joint_constraint_in_localspace(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), false, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].constraint_in_localspace; +} + +void SkeletonModification2DCCDIK::set_ccdik_joint_editor_draw_gizmo(int p_joint_idx, bool p_draw_gizmo) { + ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "CCDIK joint out of range!"); + ccdik_data_chain.write[p_joint_idx].editor_draw_gizmo = p_draw_gizmo; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DCCDIK::get_ccdik_joint_editor_draw_gizmo(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, ccdik_data_chain.size(), false, "CCDIK joint out of range!"); + return ccdik_data_chain[p_joint_idx].editor_draw_gizmo; +} + +void SkeletonModification2DCCDIK::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DCCDIK::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DCCDIK::get_target_node); + ClassDB::bind_method(D_METHOD("set_tip_node", "tip_nodepath"), &SkeletonModification2DCCDIK::set_tip_node); + ClassDB::bind_method(D_METHOD("get_tip_node"), &SkeletonModification2DCCDIK::get_tip_node); + + ClassDB::bind_method(D_METHOD("set_ccdik_data_chain_length", "length"), &SkeletonModification2DCCDIK::set_ccdik_data_chain_length); + ClassDB::bind_method(D_METHOD("get_ccdik_data_chain_length"), &SkeletonModification2DCCDIK::get_ccdik_data_chain_length); + + ClassDB::bind_method(D_METHOD("set_ccdik_joint_bone2d_node", "joint_idx", "bone2d_nodepath"), &SkeletonModification2DCCDIK::set_ccdik_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_bone2d_node", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_bone_index", "joint_idx", "bone_idx"), &SkeletonModification2DCCDIK::set_ccdik_joint_bone_index); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_bone_index", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_bone_index); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_rotate_from_joint", "joint_idx", "rotate_from_joint"), &SkeletonModification2DCCDIK::set_ccdik_joint_rotate_from_joint); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_rotate_from_joint", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_rotate_from_joint); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_enable_constraint", "joint_idx", "enable_constraint"), &SkeletonModification2DCCDIK::set_ccdik_joint_enable_constraint); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_enable_constraint", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_enable_constraint); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_constraint_angle_min", "joint_idx", "angle_min"), &SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_min); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_constraint_angle_min", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_min); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_constraint_angle_max", "joint_idx", "angle_max"), &SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_max); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_constraint_angle_max", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_max); + ClassDB::bind_method(D_METHOD("set_ccdik_joint_constraint_angle_invert", "joint_idx", "invert"), &SkeletonModification2DCCDIK::set_ccdik_joint_constraint_angle_invert); + ClassDB::bind_method(D_METHOD("get_ccdik_joint_constraint_angle_invert", "joint_idx"), &SkeletonModification2DCCDIK::get_ccdik_joint_constraint_angle_invert); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "tip_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_tip_node", "get_tip_node"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ccdik_data_chain_length", PROPERTY_HINT_RANGE, "0, 100, 1"), "set_ccdik_data_chain_length", "get_ccdik_data_chain_length"); +} + +SkeletonModification2DCCDIK::SkeletonModification2DCCDIK() { + stack = nullptr; + is_setup = false; + enabled = true; + editor_draw_gizmo = true; +} + +SkeletonModification2DCCDIK::~SkeletonModification2DCCDIK() { +} diff --git a/scene/resources/skeleton_modification_2d_ccdik.h b/scene/resources/skeleton_modification_2d_ccdik.h new file mode 100644 index 0000000000..dc48291f62 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_ccdik.h @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* skeleton_modification_2d_ccdik.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DCCDIK_H +#define SKELETONMODIFICATION2DCCDIK_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DCCDIK +/////////////////////////////////////// + +class SkeletonModification2DCCDIK : public SkeletonModification2D { + GDCLASS(SkeletonModification2DCCDIK, SkeletonModification2D); + +private: + struct CCDIK_Joint_Data2D { + int bone_idx = -1; + NodePath bone2d_node; + ObjectID bone2d_node_cache; + bool rotate_from_joint = false; + + bool enable_constraint = false; + float constraint_angle_min = 0; + float constraint_angle_max = (2.0 * Math_PI); + bool constraint_angle_invert = false; + bool constraint_in_localspace = true; + + bool editor_draw_gizmo = true; + }; + + Vector<CCDIK_Joint_Data2D> ccdik_data_chain; + + NodePath target_node; + ObjectID target_node_cache; + void update_target_cache(); + + NodePath tip_node; + ObjectID tip_node_cache; + void update_tip_cache(); + + void ccdik_joint_update_bone2d_cache(int p_joint_idx); + void _execute_ccdik_joint(int p_joint_idx, Node2D *p_target, Node2D *p_tip); + +protected: + static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + void _draw_editor_gizmo() override; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + void set_tip_node(const NodePath &p_tip_node); + NodePath get_tip_node() const; + + int get_ccdik_data_chain_length(); + void set_ccdik_data_chain_length(int p_new_length); + + void set_ccdik_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node); + NodePath get_ccdik_joint_bone2d_node(int p_joint_idx) const; + void set_ccdik_joint_bone_index(int p_joint_idx, int p_bone_idx); + int get_ccdik_joint_bone_index(int p_joint_idx) const; + + void set_ccdik_joint_rotate_from_joint(int p_joint_idx, bool p_rotate_from_joint); + bool get_ccdik_joint_rotate_from_joint(int p_joint_idx) const; + void set_ccdik_joint_enable_constraint(int p_joint_idx, bool p_constraint); + bool get_ccdik_joint_enable_constraint(int p_joint_idx) const; + void set_ccdik_joint_constraint_angle_min(int p_joint_idx, float p_angle_min); + float get_ccdik_joint_constraint_angle_min(int p_joint_idx) const; + void set_ccdik_joint_constraint_angle_max(int p_joint_idx, float p_angle_max); + float get_ccdik_joint_constraint_angle_max(int p_joint_idx) const; + void set_ccdik_joint_constraint_angle_invert(int p_joint_idx, bool p_invert); + bool get_ccdik_joint_constraint_angle_invert(int p_joint_idx) const; + void set_ccdik_joint_constraint_in_localspace(int p_joint_idx, bool p_constraint_in_localspace); + bool get_ccdik_joint_constraint_in_localspace(int p_joint_idx) const; + void set_ccdik_joint_editor_draw_gizmo(int p_joint_idx, bool p_draw_gizmo); + bool get_ccdik_joint_editor_draw_gizmo(int p_joint_idx) const; + + SkeletonModification2DCCDIK(); + ~SkeletonModification2DCCDIK(); +}; + +#endif // SKELETONMODIFICATION2DCCDIK_H diff --git a/scene/resources/skeleton_modification_2d_fabrik.cpp b/scene/resources/skeleton_modification_2d_fabrik.cpp new file mode 100644 index 0000000000..aef852f7e4 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_fabrik.cpp @@ -0,0 +1,444 @@ +/*************************************************************************/ +/* skeleton_modification_2d_fabrik.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_fabrik.h" +#include "scene/2d/skeleton_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif // TOOLS_ENABLED + +bool SkeletonModification2DFABRIK::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, fabrik_data_chain.size(), false); + + if (what == "bone2d_node") { + set_fabrik_joint_bone2d_node(which, p_value); + } else if (what == "bone_index") { + set_fabrik_joint_bone_index(which, p_value); + } else if (what == "magnet_position") { + set_fabrik_joint_magnet_position(which, p_value); + } else if (what == "use_target_rotation") { + set_fabrik_joint_use_target_rotation(which, p_value); + } + } + + return true; +} + +bool SkeletonModification2DFABRIK::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, fabrik_data_chain.size(), false); + + if (what == "bone2d_node") { + r_ret = get_fabrik_joint_bone2d_node(which); + } else if (what == "bone_index") { + r_ret = get_fabrik_joint_bone_index(which); + } else if (what == "magnet_position") { + r_ret = get_fabrik_joint_magnet_position(which); + } else if (what == "use_target_rotation") { + r_ret = get_fabrik_joint_use_target_rotation(which); + } + return true; + } + return true; +} + +void SkeletonModification2DFABRIK::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < fabrik_data_chain.size(); i++) { + String base_string = "joint_data/" + itos(i) + "/"; + + p_list->push_back(PropertyInfo(Variant::INT, base_string + "bone_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::NODE_PATH, base_string + "bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT)); + + if (i > 0) { + p_list->push_back(PropertyInfo(Variant::VECTOR2, base_string + "magnet_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } + if (i == fabrik_data_chain.size() - 1) { + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "use_target_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } + } +} + +void SkeletonModification2DFABRIK::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + + if (target_node_cache.is_null()) { + WARN_PRINT_ONCE("Target cache is out of date. Attempting to update..."); + update_target_cache(); + return; + } + + if (fabrik_data_chain.size() <= 1) { + ERR_PRINT_ONCE("FABRIK requires at least two joints to operate! Cannot execute modification!"); + return; + } + + Node2D *target = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + if (!target || !target->is_inside_tree()) { + ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!"); + return; + } + target_global_pose = target->get_global_transform(); + + if (fabrik_data_chain[0].bone2d_node_cache.is_null() && !fabrik_data_chain[0].bone2d_node.is_empty()) { + fabrik_joint_update_bone2d_cache(0); + WARN_PRINT("Bone2D cache for origin joint is out of date. Updating..."); + } + + Bone2D *origin_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[0].bone2d_node_cache)); + if (!origin_bone2d_node || !origin_bone2d_node->is_inside_tree()) { + ERR_PRINT_ONCE("Origin joint's Bone2D node is not in the scene tree. Cannot execute modification!"); + return; + } + + origin_global_pose = origin_bone2d_node->get_global_transform(); + + if (fabrik_transform_chain.size() != fabrik_data_chain.size()) { + fabrik_transform_chain.resize(fabrik_data_chain.size()); + } + + for (int i = 0; i < fabrik_data_chain.size(); i++) { + // Update the transform chain + if (fabrik_data_chain[i].bone2d_node_cache.is_null() && !fabrik_data_chain[i].bone2d_node.is_empty()) { + WARN_PRINT_ONCE("Bone2D cache for joint " + itos(i) + " is out of date.. Attempting to update..."); + fabrik_joint_update_bone2d_cache(i); + } + Bone2D *joint_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[i].bone2d_node_cache)); + if (!joint_bone2d_node) { + ERR_PRINT_ONCE("FABRIK Joint " + itos(i) + " does not have a Bone2D node set! Cannot execute modification!"); + return; + } + fabrik_transform_chain.write[i] = joint_bone2d_node->get_global_transform(); + + // Apply magnet positions + if (i == 0) { + continue; // The origin cannot use a magnet position! + } else { + Transform2D joint_trans = fabrik_transform_chain[i]; + joint_trans.set_origin(joint_trans.get_origin() + fabrik_data_chain[i].magnet_position); + fabrik_transform_chain.write[i] = joint_trans; + } + } + + Bone2D *final_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[fabrik_data_chain.size() - 1].bone2d_node_cache)); + float final_bone2d_angle = final_bone2d_node->get_global_transform().get_rotation(); + if (fabrik_data_chain[fabrik_data_chain.size() - 1].use_target_rotation) { + final_bone2d_angle = target_global_pose.get_rotation(); + } + Vector2 final_bone2d_direction = Vector2(Math::cos(final_bone2d_angle), Math::sin(final_bone2d_angle)); + float final_bone2d_length = final_bone2d_node->get_length() * MIN(final_bone2d_node->get_global_scale().x, final_bone2d_node->get_global_scale().y); + float target_distance = (final_bone2d_node->get_global_transform().get_origin() + (final_bone2d_direction * final_bone2d_length)).distance_to(target->get_global_transform().get_origin()); + chain_iterations = 0; + + while (target_distance > chain_tolarance) { + chain_backwards(); + chain_forwards(); + + final_bone2d_angle = final_bone2d_node->get_global_transform().get_rotation(); + if (fabrik_data_chain[fabrik_data_chain.size() - 1].use_target_rotation) { + final_bone2d_angle = target_global_pose.get_rotation(); + } + final_bone2d_direction = Vector2(Math::cos(final_bone2d_angle), Math::sin(final_bone2d_angle)); + target_distance = (final_bone2d_node->get_global_transform().get_origin() + (final_bone2d_direction * final_bone2d_length)).distance_to(target->get_global_transform().get_origin()); + + chain_iterations += 1; + if (chain_iterations >= chain_max_iterations) { + break; + } + } + + // Apply all of the saved transforms to the Bone2D nodes + for (int i = 0; i < fabrik_data_chain.size(); i++) { + Bone2D *joint_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[i].bone2d_node_cache)); + if (!joint_bone2d_node) { + ERR_PRINT_ONCE("FABRIK Joint " + itos(i) + " does not have a Bone2D node set!"); + continue; + } + Transform2D chain_trans = fabrik_transform_chain[i]; + + // Apply rotation + if (i + 1 < fabrik_data_chain.size()) { + chain_trans = chain_trans.looking_at(fabrik_transform_chain[i + 1].get_origin()); + } else { + if (fabrik_data_chain[i].use_target_rotation) { + chain_trans.set_rotation(target_global_pose.get_rotation()); + } else { + chain_trans = chain_trans.looking_at(target_global_pose.get_origin()); + } + } + // Adjust for the bone angle + chain_trans.set_rotation(chain_trans.get_rotation() - joint_bone2d_node->get_bone_angle()); + + // Reset scale + chain_trans.set_scale(joint_bone2d_node->get_global_transform().get_scale()); + + // Apply to the bone, and to the override + joint_bone2d_node->set_global_transform(chain_trans); + stack->skeleton->set_bone_local_pose_override(fabrik_data_chain[i].bone_idx, joint_bone2d_node->get_transform(), stack->strength, true); + } +} + +void SkeletonModification2DFABRIK::chain_backwards() { + int final_joint_index = fabrik_data_chain.size() - 1; + Bone2D *final_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[final_joint_index].bone2d_node_cache)); + Transform2D final_bone2d_trans = fabrik_transform_chain[final_joint_index]; + + // Set the rotation of the tip bone + final_bone2d_trans = final_bone2d_trans.looking_at(target_global_pose.get_origin()); + + // Set the position of the tip bone + float final_bone2d_angle = final_bone2d_trans.get_rotation(); + if (fabrik_data_chain[final_joint_index].use_target_rotation) { + final_bone2d_angle = target_global_pose.get_rotation(); + } + Vector2 final_bone2d_direction = Vector2(Math::cos(final_bone2d_angle), Math::sin(final_bone2d_angle)); + float final_bone2d_length = final_bone2d_node->get_length() * MIN(final_bone2d_node->get_global_scale().x, final_bone2d_node->get_global_scale().y); + final_bone2d_trans.set_origin(target_global_pose.get_origin() - (final_bone2d_direction * final_bone2d_length)); + + // Save the transform + fabrik_transform_chain.write[final_joint_index] = final_bone2d_trans; + + int i = final_joint_index; + while (i >= 1) { + Transform2D previous_pose = fabrik_transform_chain[i]; + i -= 1; + Bone2D *current_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[i].bone2d_node_cache)); + Transform2D current_pose = fabrik_transform_chain[i]; + + float current_bone2d_node_length = current_bone2d_node->get_length() * MIN(current_bone2d_node->get_global_scale().x, current_bone2d_node->get_global_scale().y); + float length = current_bone2d_node_length / (previous_pose.get_origin() - current_pose.get_origin()).length(); + Vector2 finish_position = previous_pose.get_origin().lerp(current_pose.get_origin(), length); + current_pose.set_origin(finish_position); + + // Save the transform + fabrik_transform_chain.write[i] = current_pose; + } +} + +void SkeletonModification2DFABRIK::chain_forwards() { + Transform2D origin_bone2d_trans = fabrik_transform_chain[0]; + origin_bone2d_trans.set_origin(origin_global_pose.get_origin()); + // Save the position + fabrik_transform_chain.write[0] = origin_bone2d_trans; + + for (int i = 0; i < fabrik_data_chain.size() - 1; i++) { + Bone2D *current_bone2d_node = Object::cast_to<Bone2D>(ObjectDB::get_instance(fabrik_data_chain[i].bone2d_node_cache)); + Transform2D current_pose = fabrik_transform_chain[i]; + Transform2D next_pose = fabrik_transform_chain[i + 1]; + + float current_bone2d_node_length = current_bone2d_node->get_length() * MIN(current_bone2d_node->get_global_scale().x, current_bone2d_node->get_global_scale().y); + float length = current_bone2d_node_length / (current_pose.get_origin() - next_pose.get_origin()).length(); + Vector2 finish_position = current_pose.get_origin().lerp(next_pose.get_origin(), length); + current_pose.set_origin(finish_position); + + // Apply to the bone + fabrik_transform_chain.write[i + 1] = current_pose; + } +} + +void SkeletonModification2DFABRIK::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack != nullptr) { + is_setup = true; + update_target_cache(); + } +} + +void SkeletonModification2DFABRIK::update_target_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + return; + } + + target_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(target_node)) { + Node *node = stack->skeleton->get_node(target_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update target cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update target cache: node is not in scene tree!"); + target_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DFABRIK::fabrik_joint_update_bone2d_cache(int p_joint_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update FABRIK Bone2D cache: modification is not properly setup!"); + return; + } + + fabrik_data_chain.write[p_joint_idx].bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(fabrik_data_chain[p_joint_idx].bone2d_node)) { + Node *node = stack->skeleton->get_node(fabrik_data_chain[p_joint_idx].bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update FABRIK joint " + itos(p_joint_idx) + " Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update FABRIK joint " + itos(p_joint_idx) + " Bone2D cache: node is not in scene tree!"); + fabrik_data_chain.write[p_joint_idx].bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + fabrik_data_chain.write[p_joint_idx].bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("FABRIK joint " + itos(p_joint_idx) + " Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + } + } + } +} + +void SkeletonModification2DFABRIK::set_target_node(const NodePath &p_target_node) { + target_node = p_target_node; + update_target_cache(); +} + +NodePath SkeletonModification2DFABRIK::get_target_node() const { + return target_node; +} + +void SkeletonModification2DFABRIK::set_fabrik_data_chain_length(int p_length) { + fabrik_data_chain.resize(p_length); + notify_property_list_changed(); +} + +int SkeletonModification2DFABRIK::get_fabrik_data_chain_length() { + return fabrik_data_chain.size(); +} + +void SkeletonModification2DFABRIK::set_fabrik_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node) { + ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "FABRIK joint out of range!"); + fabrik_data_chain.write[p_joint_idx].bone2d_node = p_target_node; + fabrik_joint_update_bone2d_cache(p_joint_idx); + + notify_property_list_changed(); +} + +NodePath SkeletonModification2DFABRIK::get_fabrik_joint_bone2d_node(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, fabrik_data_chain.size(), NodePath(), "FABRIK joint out of range!"); + return fabrik_data_chain[p_joint_idx].bone2d_node; +} + +void SkeletonModification2DFABRIK::set_fabrik_joint_bone_index(int p_joint_idx, int p_bone_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "FABRIK joint out of range!"); + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + fabrik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + fabrik_data_chain.write[p_joint_idx].bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + fabrik_data_chain.write[p_joint_idx].bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("Cannot verify the FABRIK joint " + itos(p_joint_idx) + " bone index for this modification..."); + fabrik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("Cannot verify the FABRIK joint " + itos(p_joint_idx) + " bone index for this modification..."); + fabrik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +int SkeletonModification2DFABRIK::get_fabrik_joint_bone_index(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, fabrik_data_chain.size(), -1, "FABRIK joint out of range!"); + return fabrik_data_chain[p_joint_idx].bone_idx; +} + +void SkeletonModification2DFABRIK::set_fabrik_joint_magnet_position(int p_joint_idx, Vector2 p_magnet_position) { + ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "FABRIK joint out of range!"); + fabrik_data_chain.write[p_joint_idx].magnet_position = p_magnet_position; +} + +Vector2 SkeletonModification2DFABRIK::get_fabrik_joint_magnet_position(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, fabrik_data_chain.size(), Vector2(), "FABRIK joint out of range!"); + return fabrik_data_chain[p_joint_idx].magnet_position; +} + +void SkeletonModification2DFABRIK::set_fabrik_joint_use_target_rotation(int p_joint_idx, bool p_use_target_rotation) { + ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "FABRIK joint out of range!"); + fabrik_data_chain.write[p_joint_idx].use_target_rotation = p_use_target_rotation; +} + +bool SkeletonModification2DFABRIK::get_fabrik_joint_use_target_rotation(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, fabrik_data_chain.size(), false, "FABRIK joint out of range!"); + return fabrik_data_chain[p_joint_idx].use_target_rotation; +} + +void SkeletonModification2DFABRIK::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DFABRIK::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DFABRIK::get_target_node); + + ClassDB::bind_method(D_METHOD("set_fabrik_data_chain_length", "length"), &SkeletonModification2DFABRIK::set_fabrik_data_chain_length); + ClassDB::bind_method(D_METHOD("get_fabrik_data_chain_length"), &SkeletonModification2DFABRIK::get_fabrik_data_chain_length); + + ClassDB::bind_method(D_METHOD("set_fabrik_joint_bone2d_node", "joint_idx", "bone2d_nodepath"), &SkeletonModification2DFABRIK::set_fabrik_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("get_fabrik_joint_bone2d_node", "joint_idx"), &SkeletonModification2DFABRIK::get_fabrik_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("set_fabrik_joint_bone_index", "joint_idx", "bone_idx"), &SkeletonModification2DFABRIK::set_fabrik_joint_bone_index); + ClassDB::bind_method(D_METHOD("get_fabrik_joint_bone_index", "joint_idx"), &SkeletonModification2DFABRIK::get_fabrik_joint_bone_index); + ClassDB::bind_method(D_METHOD("set_fabrik_joint_magnet_position", "joint_idx", "magnet_position"), &SkeletonModification2DFABRIK::set_fabrik_joint_magnet_position); + ClassDB::bind_method(D_METHOD("get_fabrik_joint_magnet_position", "joint_idx"), &SkeletonModification2DFABRIK::get_fabrik_joint_magnet_position); + ClassDB::bind_method(D_METHOD("set_fabrik_joint_use_target_rotation", "joint_idx", "use_target_rotation"), &SkeletonModification2DFABRIK::set_fabrik_joint_use_target_rotation); + ClassDB::bind_method(D_METHOD("get_fabrik_joint_use_target_rotation", "joint_idx"), &SkeletonModification2DFABRIK::get_fabrik_joint_use_target_rotation); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fabrik_data_chain_length", PROPERTY_HINT_RANGE, "0, 100, 1"), "set_fabrik_data_chain_length", "get_fabrik_data_chain_length"); +} + +SkeletonModification2DFABRIK::SkeletonModification2DFABRIK() { + stack = nullptr; + is_setup = false; + enabled = true; + editor_draw_gizmo = false; +} + +SkeletonModification2DFABRIK::~SkeletonModification2DFABRIK() { +} diff --git a/scene/resources/skeleton_modification_2d_fabrik.h b/scene/resources/skeleton_modification_2d_fabrik.h new file mode 100644 index 0000000000..79e0106e26 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_fabrik.h @@ -0,0 +1,108 @@ +/*************************************************************************/ +/* skeleton_modification_2d_fabrik.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DFABRIK_H +#define SKELETONMODIFICATION2DFABRIK_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DFABRIK +/////////////////////////////////////// + +class SkeletonModification2DFABRIK : public SkeletonModification2D { + GDCLASS(SkeletonModification2DFABRIK, SkeletonModification2D); + +private: + struct FABRIK_Joint_Data2D { + int bone_idx = -1; + NodePath bone2d_node; + ObjectID bone2d_node_cache; + + Vector2 magnet_position = Vector2(0, 0); + bool use_target_rotation = false; + + bool editor_draw_gizmo = true; + }; + + Vector<FABRIK_Joint_Data2D> fabrik_data_chain; + + // Unlike in 3D, we need a vector of Transform2D objects to perform FABRIK. + // This is because FABRIK (unlike CCDIK) needs to operate on transforms that are NOT + // affected by each other, making the transforms stored in Bone2D unusable, as well as those in Skeleton2D. + // For this reason, this modification stores a vector of Transform2Ds used for the calculations, which are then applied at the end. + Vector<Transform2D> fabrik_transform_chain; + + NodePath target_node; + ObjectID target_node_cache; + void update_target_cache(); + + float chain_tolarance = 0.01; + int chain_max_iterations = 10; + int chain_iterations = 0; + Transform2D target_global_pose = Transform2D(); + Transform2D origin_global_pose = Transform2D(); + + void fabrik_joint_update_bone2d_cache(int p_joint_idx); + void chain_backwards(); + void chain_forwards(); + +protected: + static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + + int get_fabrik_data_chain_length(); + void set_fabrik_data_chain_length(int p_new_length); + + void set_fabrik_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node); + NodePath get_fabrik_joint_bone2d_node(int p_joint_idx) const; + void set_fabrik_joint_bone_index(int p_joint_idx, int p_bone_idx); + int get_fabrik_joint_bone_index(int p_joint_idx) const; + + void set_fabrik_joint_magnet_position(int p_joint_idx, Vector2 p_magnet_position); + Vector2 get_fabrik_joint_magnet_position(int p_joint_idx) const; + void set_fabrik_joint_use_target_rotation(int p_joint_idx, bool p_use_target_rotation); + bool get_fabrik_joint_use_target_rotation(int p_joint_idx) const; + + SkeletonModification2DFABRIK(); + ~SkeletonModification2DFABRIK(); +}; + +#endif // SKELETONMODIFICATION2DFABRIK_H diff --git a/scene/resources/skeleton_modification_2d_jiggle.cpp b/scene/resources/skeleton_modification_2d_jiggle.cpp new file mode 100644 index 0000000000..2547083336 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_jiggle.cpp @@ -0,0 +1,564 @@ +/*************************************************************************/ +/* skeleton_modification_2d_jiggle.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_jiggle.h" +#include "scene/2d/skeleton_2d.h" + +bool SkeletonModification2DJiggle::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, jiggle_data_chain.size(), false); + + if (what == "bone2d_node") { + set_jiggle_joint_bone2d_node(which, p_value); + } else if (what == "bone_index") { + set_jiggle_joint_bone_index(which, p_value); + } else if (what == "override_defaults") { + set_jiggle_joint_override(which, p_value); + } else if (what == "stiffness") { + set_jiggle_joint_stiffness(which, p_value); + } else if (what == "mass") { + set_jiggle_joint_mass(which, p_value); + } else if (what == "damping") { + set_jiggle_joint_damping(which, p_value); + } else if (what == "use_gravity") { + set_jiggle_joint_use_gravity(which, p_value); + } else if (what == "gravity") { + set_jiggle_joint_gravity(which, p_value); + } + return true; + } else { + if (path == "use_colliders") { + set_use_colliders(p_value); + } else if (path == "collision_mask") { + set_collision_mask(p_value); + } + } + return true; +} + +bool SkeletonModification2DJiggle::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("joint_data/")) { + int which = path.get_slicec('/', 1).to_int(); + String what = path.get_slicec('/', 2); + ERR_FAIL_INDEX_V(which, jiggle_data_chain.size(), false); + + if (what == "bone2d_node") { + r_ret = get_jiggle_joint_bone2d_node(which); + } else if (what == "bone_index") { + r_ret = get_jiggle_joint_bone_index(which); + } else if (what == "override_defaults") { + r_ret = get_jiggle_joint_override(which); + } else if (what == "stiffness") { + r_ret = get_jiggle_joint_stiffness(which); + } else if (what == "mass") { + r_ret = get_jiggle_joint_mass(which); + } else if (what == "damping") { + r_ret = get_jiggle_joint_damping(which); + } else if (what == "use_gravity") { + r_ret = get_jiggle_joint_use_gravity(which); + } else if (what == "gravity") { + r_ret = get_jiggle_joint_gravity(which); + } + return true; + } else { + if (path == "use_colliders") { + r_ret = get_use_colliders(); + } else if (path == "collision_mask") { + r_ret = get_collision_mask(); + } + } + return true; +} + +void SkeletonModification2DJiggle::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::BOOL, "use_colliders", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (use_colliders) { + p_list->push_back(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS, "", PROPERTY_USAGE_DEFAULT)); + } + + for (int i = 0; i < jiggle_data_chain.size(); i++) { + String base_string = "joint_data/" + itos(i) + "/"; + + p_list->push_back(PropertyInfo(Variant::INT, base_string + "bone_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::NODE_PATH, base_string + "bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "override_defaults", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + + if (jiggle_data_chain[i].override_defaults) { + p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "stiffness", PROPERTY_HINT_RANGE, "0, 1000, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "mass", PROPERTY_HINT_RANGE, "0, 1000, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "damping", PROPERTY_HINT_RANGE, "0, 1, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "use_gravity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (jiggle_data_chain[i].use_gravity) { + p_list->push_back(PropertyInfo(Variant::VECTOR2, base_string + "gravity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } + } + } +} + +void SkeletonModification2DJiggle::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + if (target_node_cache.is_null()) { + WARN_PRINT_ONCE("Target cache is out of date. Attempting to update..."); + update_target_cache(); + return; + } + Node2D *target = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + if (!target || !target->is_inside_tree()) { + ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!"); + return; + } + + for (int i = 0; i < jiggle_data_chain.size(); i++) { + _execute_jiggle_joint(i, target, p_delta); + } +} + +void SkeletonModification2DJiggle::_execute_jiggle_joint(int p_joint_idx, Node2D *p_target, float p_delta) { + // Adopted from: https://wiki.unity3d.com/index.php/JiggleBone + // With modifications by TwistedTwigleg. + + if (jiggle_data_chain[p_joint_idx].bone_idx <= -1 || jiggle_data_chain[p_joint_idx].bone_idx > stack->skeleton->get_bone_count()) { + ERR_PRINT_ONCE("Jiggle joint " + itos(p_joint_idx) + " bone index is invalid. Cannot execute modification on joint..."); + return; + } + + if (jiggle_data_chain[p_joint_idx].bone2d_node_cache.is_null() && !jiggle_data_chain[p_joint_idx].bone2d_node.is_empty()) { + WARN_PRINT_ONCE("Bone2D cache for joint " + itos(p_joint_idx) + " is out of date. Updating..."); + jiggle_joint_update_bone2d_cache(p_joint_idx); + } + + Bone2D *operation_bone = stack->skeleton->get_bone(jiggle_data_chain[p_joint_idx].bone_idx); + if (!operation_bone) { + ERR_PRINT_ONCE("Jiggle joint " + itos(p_joint_idx) + " does not have a Bone2D node or it cannot be found!"); + return; + } + + Transform2D operation_bone_trans = operation_bone->get_global_transform(); + Vector2 target_position = p_target->get_global_transform().get_origin(); + + jiggle_data_chain.write[p_joint_idx].force = (target_position - jiggle_data_chain[p_joint_idx].dynamic_position) * jiggle_data_chain[p_joint_idx].stiffness * p_delta; + + if (jiggle_data_chain[p_joint_idx].use_gravity) { + jiggle_data_chain.write[p_joint_idx].force += jiggle_data_chain[p_joint_idx].gravity * p_delta; + } + + jiggle_data_chain.write[p_joint_idx].acceleration = jiggle_data_chain[p_joint_idx].force / jiggle_data_chain[p_joint_idx].mass; + jiggle_data_chain.write[p_joint_idx].velocity += jiggle_data_chain[p_joint_idx].acceleration * (1 - jiggle_data_chain[p_joint_idx].damping); + + jiggle_data_chain.write[p_joint_idx].dynamic_position += jiggle_data_chain[p_joint_idx].velocity + jiggle_data_chain[p_joint_idx].force; + jiggle_data_chain.write[p_joint_idx].dynamic_position += operation_bone_trans.get_origin() - jiggle_data_chain[p_joint_idx].last_position; + jiggle_data_chain.write[p_joint_idx].last_position = operation_bone_trans.get_origin(); + + // Collision detection/response + if (use_colliders) { + if (execution_mode == SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_physics_process) { + Ref<World2D> world_2d = stack->skeleton->get_world_2d(); + ERR_FAIL_COND(world_2d.is_null()); + PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); + PhysicsDirectSpaceState2D::RayResult ray_result; + + // Add exception support? + bool ray_hit = space_state->intersect_ray(operation_bone_trans.get_origin(), jiggle_data_chain[p_joint_idx].dynamic_position, + ray_result, Set<RID>(), collision_mask); + + if (ray_hit) { + jiggle_data_chain.write[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position; + jiggle_data_chain.write[p_joint_idx].acceleration = Vector2(0, 0); + jiggle_data_chain.write[p_joint_idx].velocity = Vector2(0, 0); + } else { + jiggle_data_chain.write[p_joint_idx].last_noncollision_position = jiggle_data_chain[p_joint_idx].dynamic_position; + } + } else { + WARN_PRINT_ONCE("Jiggle 2D modifier: You cannot detect colliders without the stack mode being set to _physics_process!"); + } + } + + // Rotate the bone using the dynamic position! + operation_bone_trans = operation_bone_trans.looking_at(jiggle_data_chain[p_joint_idx].dynamic_position); + operation_bone_trans.set_rotation(operation_bone_trans.get_rotation() - operation_bone->get_bone_angle()); + + // Reset scale + operation_bone_trans.set_scale(operation_bone->get_global_transform().get_scale()); + + operation_bone->set_global_transform(operation_bone_trans); + stack->skeleton->set_bone_local_pose_override(jiggle_data_chain[p_joint_idx].bone_idx, operation_bone->get_transform(), stack->strength, true); +} + +void SkeletonModification2DJiggle::_update_jiggle_joint_data() { + for (int i = 0; i < jiggle_data_chain.size(); i++) { + if (!jiggle_data_chain[i].override_defaults) { + set_jiggle_joint_stiffness(i, stiffness); + set_jiggle_joint_mass(i, mass); + set_jiggle_joint_damping(i, damping); + set_jiggle_joint_use_gravity(i, use_gravity); + set_jiggle_joint_gravity(i, gravity); + } + } +} + +void SkeletonModification2DJiggle::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack) { + is_setup = true; + + if (stack->skeleton) { + for (int i = 0; i < jiggle_data_chain.size(); i++) { + int bone_idx = jiggle_data_chain[i].bone_idx; + if (bone_idx > 0 && bone_idx < stack->skeleton->get_bone_count()) { + Bone2D *bone2d_node = stack->skeleton->get_bone(bone_idx); + jiggle_data_chain.write[i].dynamic_position = bone2d_node->get_global_transform().get_origin(); + } + } + } + + update_target_cache(); + } +} + +void SkeletonModification2DJiggle::update_target_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + return; + } + + target_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(target_node)) { + Node *node = stack->skeleton->get_node(target_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update target cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update target cache: node is not in scene tree!"); + target_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DJiggle::jiggle_joint_update_bone2d_cache(int p_joint_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update Jiggle " + itos(p_joint_idx) + " Bone2D cache: modification is not properly setup!"); + return; + } + + jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(jiggle_data_chain[p_joint_idx].bone2d_node)) { + Node *node = stack->skeleton->get_node(jiggle_data_chain[p_joint_idx].bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: node is not in scene tree!"); + jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + jiggle_data_chain.write[p_joint_idx].bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + } + } + } +} + +void SkeletonModification2DJiggle::set_target_node(const NodePath &p_target_node) { + target_node = p_target_node; + update_target_cache(); +} + +NodePath SkeletonModification2DJiggle::get_target_node() const { + return target_node; +} + +void SkeletonModification2DJiggle::set_stiffness(float p_stiffness) { + ERR_FAIL_COND_MSG(p_stiffness < 0, "Stiffness cannot be set to a negative value!"); + stiffness = p_stiffness; + _update_jiggle_joint_data(); +} + +float SkeletonModification2DJiggle::get_stiffness() const { + return stiffness; +} + +void SkeletonModification2DJiggle::set_mass(float p_mass) { + ERR_FAIL_COND_MSG(p_mass < 0, "Mass cannot be set to a negative value!"); + mass = p_mass; + _update_jiggle_joint_data(); +} + +float SkeletonModification2DJiggle::get_mass() const { + return mass; +} + +void SkeletonModification2DJiggle::set_damping(float p_damping) { + ERR_FAIL_COND_MSG(p_damping < 0, "Damping cannot be set to a negative value!"); + ERR_FAIL_COND_MSG(p_damping > 1, "Damping cannot be more than one!"); + damping = p_damping; + _update_jiggle_joint_data(); +} + +float SkeletonModification2DJiggle::get_damping() const { + return damping; +} + +void SkeletonModification2DJiggle::set_use_gravity(bool p_use_gravity) { + use_gravity = p_use_gravity; + _update_jiggle_joint_data(); +} + +bool SkeletonModification2DJiggle::get_use_gravity() const { + return use_gravity; +} + +void SkeletonModification2DJiggle::set_gravity(Vector2 p_gravity) { + gravity = p_gravity; + _update_jiggle_joint_data(); +} + +Vector2 SkeletonModification2DJiggle::get_gravity() const { + return gravity; +} + +void SkeletonModification2DJiggle::set_use_colliders(bool p_use_colliders) { + use_colliders = p_use_colliders; + notify_property_list_changed(); +} + +bool SkeletonModification2DJiggle::get_use_colliders() const { + return use_colliders; +} + +void SkeletonModification2DJiggle::set_collision_mask(int p_mask) { + collision_mask = p_mask; +} + +int SkeletonModification2DJiggle::get_collision_mask() const { + return collision_mask; +} + +// Jiggle joint data functions +int SkeletonModification2DJiggle::get_jiggle_data_chain_length() { + return jiggle_data_chain.size(); +} + +void SkeletonModification2DJiggle::set_jiggle_data_chain_length(int p_length) { + ERR_FAIL_COND(p_length < 0); + jiggle_data_chain.resize(p_length); + notify_property_list_changed(); +} + +void SkeletonModification2DJiggle::set_jiggle_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node) { + ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Jiggle joint out of range!"); + jiggle_data_chain.write[p_joint_idx].bone2d_node = p_target_node; + jiggle_joint_update_bone2d_cache(p_joint_idx); + + notify_property_list_changed(); +} + +NodePath SkeletonModification2DJiggle::get_jiggle_joint_bone2d_node(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, jiggle_data_chain.size(), NodePath(), "Jiggle joint out of range!"); + return jiggle_data_chain[p_joint_idx].bone2d_node; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_bone_index(int p_joint_idx, int p_bone_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Jiggle joint out of range!"); + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + jiggle_data_chain.write[p_joint_idx].bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("Cannot verify the Jiggle joint " + itos(p_joint_idx) + " bone index for this modification..."); + jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("Cannot verify the Jiggle joint " + itos(p_joint_idx) + " bone index for this modification..."); + jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +int SkeletonModification2DJiggle::get_jiggle_joint_bone_index(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, jiggle_data_chain.size(), -1, "Jiggle joint out of range!"); + return jiggle_data_chain[p_joint_idx].bone_idx; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_override(int p_joint_idx, bool p_override) { + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].override_defaults = p_override; + _update_jiggle_joint_data(); + notify_property_list_changed(); +} + +bool SkeletonModification2DJiggle::get_jiggle_joint_override(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), false); + return jiggle_data_chain[p_joint_idx].override_defaults; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_stiffness(int p_joint_idx, float p_stiffness) { + ERR_FAIL_COND_MSG(p_stiffness < 0, "Stiffness cannot be set to a negative value!"); + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].stiffness = p_stiffness; +} + +float SkeletonModification2DJiggle::get_jiggle_joint_stiffness(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1); + return jiggle_data_chain[p_joint_idx].stiffness; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_mass(int p_joint_idx, float p_mass) { + ERR_FAIL_COND_MSG(p_mass < 0, "Mass cannot be set to a negative value!"); + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].mass = p_mass; +} + +float SkeletonModification2DJiggle::get_jiggle_joint_mass(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1); + return jiggle_data_chain[p_joint_idx].mass; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_damping(int p_joint_idx, float p_damping) { + ERR_FAIL_COND_MSG(p_damping < 0, "Damping cannot be set to a negative value!"); + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].damping = p_damping; +} + +float SkeletonModification2DJiggle::get_jiggle_joint_damping(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1); + return jiggle_data_chain[p_joint_idx].damping; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_use_gravity(int p_joint_idx, bool p_use_gravity) { + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].use_gravity = p_use_gravity; + notify_property_list_changed(); +} + +bool SkeletonModification2DJiggle::get_jiggle_joint_use_gravity(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), false); + return jiggle_data_chain[p_joint_idx].use_gravity; +} + +void SkeletonModification2DJiggle::set_jiggle_joint_gravity(int p_joint_idx, Vector2 p_gravity) { + ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size()); + jiggle_data_chain.write[p_joint_idx].gravity = p_gravity; +} + +Vector2 SkeletonModification2DJiggle::get_jiggle_joint_gravity(int p_joint_idx) const { + ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), Vector2(0, 0)); + return jiggle_data_chain[p_joint_idx].gravity; +} + +void SkeletonModification2DJiggle::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DJiggle::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DJiggle::get_target_node); + + ClassDB::bind_method(D_METHOD("set_jiggle_data_chain_length", "length"), &SkeletonModification2DJiggle::set_jiggle_data_chain_length); + ClassDB::bind_method(D_METHOD("get_jiggle_data_chain_length"), &SkeletonModification2DJiggle::get_jiggle_data_chain_length); + + ClassDB::bind_method(D_METHOD("set_stiffness", "stiffness"), &SkeletonModification2DJiggle::set_stiffness); + ClassDB::bind_method(D_METHOD("get_stiffness"), &SkeletonModification2DJiggle::get_stiffness); + ClassDB::bind_method(D_METHOD("set_mass", "mass"), &SkeletonModification2DJiggle::set_mass); + ClassDB::bind_method(D_METHOD("get_mass"), &SkeletonModification2DJiggle::get_mass); + ClassDB::bind_method(D_METHOD("set_damping", "damping"), &SkeletonModification2DJiggle::set_damping); + ClassDB::bind_method(D_METHOD("get_damping"), &SkeletonModification2DJiggle::get_damping); + ClassDB::bind_method(D_METHOD("set_use_gravity", "use_gravity"), &SkeletonModification2DJiggle::set_use_gravity); + ClassDB::bind_method(D_METHOD("get_use_gravity"), &SkeletonModification2DJiggle::get_use_gravity); + ClassDB::bind_method(D_METHOD("set_gravity", "gravity"), &SkeletonModification2DJiggle::set_gravity); + ClassDB::bind_method(D_METHOD("get_gravity"), &SkeletonModification2DJiggle::get_gravity); + + ClassDB::bind_method(D_METHOD("set_use_colliders", "use_colliders"), &SkeletonModification2DJiggle::set_use_colliders); + ClassDB::bind_method(D_METHOD("get_use_colliders"), &SkeletonModification2DJiggle::get_use_colliders); + ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SkeletonModification2DJiggle::set_collision_mask); + ClassDB::bind_method(D_METHOD("get_collision_mask"), &SkeletonModification2DJiggle::get_collision_mask); + + // Jiggle joint data functions + ClassDB::bind_method(D_METHOD("set_jiggle_joint_bone2d_node", "joint_idx", "bone2d_node"), &SkeletonModification2DJiggle::set_jiggle_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_bone2d_node", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_bone2d_node); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_bone_index", "joint_idx", "bone_idx"), &SkeletonModification2DJiggle::set_jiggle_joint_bone_index); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_bone_index", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_bone_index); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_override", "joint_idx", "override"), &SkeletonModification2DJiggle::set_jiggle_joint_override); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_override", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_override); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_stiffness", "joint_idx", "stiffness"), &SkeletonModification2DJiggle::set_jiggle_joint_stiffness); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_stiffness", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_stiffness); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_mass", "joint_idx", "mass"), &SkeletonModification2DJiggle::set_jiggle_joint_mass); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_mass", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_mass); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_damping", "joint_idx", "damping"), &SkeletonModification2DJiggle::set_jiggle_joint_damping); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_damping", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_damping); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_use_gravity", "joint_idx", "use_gravity"), &SkeletonModification2DJiggle::set_jiggle_joint_use_gravity); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_use_gravity", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_use_gravity); + ClassDB::bind_method(D_METHOD("set_jiggle_joint_gravity", "joint_idx", "gravity"), &SkeletonModification2DJiggle::set_jiggle_joint_gravity); + ClassDB::bind_method(D_METHOD("get_jiggle_joint_gravity", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_gravity); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "jiggle_data_chain_length", PROPERTY_HINT_RANGE, "0,100,1"), "set_jiggle_data_chain_length", "get_jiggle_data_chain_length"); + ADD_GROUP("Default Joint Settings", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stiffness"), "set_stiffness", "get_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass"), "set_mass", "get_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0, 1, 0.01"), "set_damping", "get_damping"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_gravity"), "set_use_gravity", "get_use_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity"); + ADD_GROUP("", ""); +} + +SkeletonModification2DJiggle::SkeletonModification2DJiggle() { + stack = nullptr; + is_setup = false; + jiggle_data_chain = Vector<Jiggle_Joint_Data2D>(); + stiffness = 3; + mass = 0.75; + damping = 0.75; + use_gravity = false; + gravity = Vector2(0, 6.0); + enabled = true; + editor_draw_gizmo = false; // Nothing to really show in a gizmo right now. +} + +SkeletonModification2DJiggle::~SkeletonModification2DJiggle() { +} diff --git a/scene/resources/skeleton_modification_2d_jiggle.h b/scene/resources/skeleton_modification_2d_jiggle.h new file mode 100644 index 0000000000..e24038a1db --- /dev/null +++ b/scene/resources/skeleton_modification_2d_jiggle.h @@ -0,0 +1,139 @@ +/*************************************************************************/ +/* skeleton_modification_2d_jiggle.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DJIGGLE_H +#define SKELETONMODIFICATION2DJIGGLE_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DJIGGLE +/////////////////////////////////////// + +class SkeletonModification2DJiggle : public SkeletonModification2D { + GDCLASS(SkeletonModification2DJiggle, SkeletonModification2D); + +private: + struct Jiggle_Joint_Data2D { + int bone_idx = -1; + NodePath bone2d_node; + ObjectID bone2d_node_cache; + + bool override_defaults = false; + float stiffness = 3; + float mass = 0.75; + float damping = 0.75; + bool use_gravity = false; + Vector2 gravity = Vector2(0, 6.0); + + Vector2 force = Vector2(0, 0); + Vector2 acceleration = Vector2(0, 0); + Vector2 velocity = Vector2(0, 0); + Vector2 last_position = Vector2(0, 0); + Vector2 dynamic_position = Vector2(0, 0); + + Vector2 last_noncollision_position = Vector2(0, 0); + }; + + Vector<Jiggle_Joint_Data2D> jiggle_data_chain; + + NodePath target_node; + ObjectID target_node_cache; + void update_target_cache(); + + float stiffness = 3; + float mass = 0.75; + float damping = 0.75; + bool use_gravity = false; + Vector2 gravity = Vector2(0, 6); + + bool use_colliders = false; + uint32_t collision_mask = 1; + + void jiggle_joint_update_bone2d_cache(int p_joint_idx); + void _execute_jiggle_joint(int p_joint_idx, Node2D *p_target, float p_delta); + void _update_jiggle_joint_data(); + +protected: + static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + + void set_stiffness(float p_stiffness); + float get_stiffness() const; + void set_mass(float p_mass); + float get_mass() const; + void set_damping(float p_damping); + float get_damping() const; + void set_use_gravity(bool p_use_gravity); + bool get_use_gravity() const; + void set_gravity(Vector2 p_gravity); + Vector2 get_gravity() const; + + void set_use_colliders(bool p_use_colliders); + bool get_use_colliders() const; + void set_collision_mask(int p_mask); + int get_collision_mask() const; + + int get_jiggle_data_chain_length(); + void set_jiggle_data_chain_length(int p_new_length); + + void set_jiggle_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node); + NodePath get_jiggle_joint_bone2d_node(int p_joint_idx) const; + void set_jiggle_joint_bone_index(int p_joint_idx, int p_bone_idx); + int get_jiggle_joint_bone_index(int p_joint_idx) const; + + void set_jiggle_joint_override(int p_joint_idx, bool p_override); + bool get_jiggle_joint_override(int p_joint_idx) const; + void set_jiggle_joint_stiffness(int p_joint_idx, float p_stiffness); + float get_jiggle_joint_stiffness(int p_joint_idx) const; + void set_jiggle_joint_mass(int p_joint_idx, float p_mass); + float get_jiggle_joint_mass(int p_joint_idx) const; + void set_jiggle_joint_damping(int p_joint_idx, float p_damping); + float get_jiggle_joint_damping(int p_joint_idx) const; + void set_jiggle_joint_use_gravity(int p_joint_idx, bool p_use_gravity); + bool get_jiggle_joint_use_gravity(int p_joint_idx) const; + void set_jiggle_joint_gravity(int p_joint_idx, Vector2 p_gravity); + Vector2 get_jiggle_joint_gravity(int p_joint_idx) const; + + SkeletonModification2DJiggle(); + ~SkeletonModification2DJiggle(); +}; + +#endif // SKELETONMODIFICATION2DJIGGLE_H diff --git a/scene/resources/skeleton_modification_2d_lookat.cpp b/scene/resources/skeleton_modification_2d_lookat.cpp new file mode 100644 index 0000000000..fd5c8c7cc2 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_lookat.cpp @@ -0,0 +1,407 @@ +/*************************************************************************/ +/* skeleton_modification_2d_lookat.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_lookat.h" +#include "scene/2d/skeleton_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif // TOOLS_ENABLED + +bool SkeletonModification2DLookAt::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("enable_constraint")) { + set_enable_constraint(p_value); + } else if (path.begins_with("constraint_angle_min")) { + set_constraint_angle_min(Math::deg2rad(float(p_value))); + } else if (path.begins_with("constraint_angle_max")) { + set_constraint_angle_max(Math::deg2rad(float(p_value))); + } else if (path.begins_with("constraint_angle_invert")) { + set_constraint_angle_invert(p_value); + } else if (path.begins_with("constraint_in_localspace")) { + set_constraint_in_localspace(p_value); + } else if (path.begins_with("additional_rotation")) { + set_additional_rotation(Math::deg2rad(float(p_value))); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + set_editor_draw_gizmo(p_value); + } +#endif // TOOLS_ENABLED + + return true; +} + +bool SkeletonModification2DLookAt::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("enable_constraint")) { + r_ret = get_enable_constraint(); + } else if (path.begins_with("constraint_angle_min")) { + r_ret = Math::rad2deg(get_constraint_angle_min()); + } else if (path.begins_with("constraint_angle_max")) { + r_ret = Math::rad2deg(get_constraint_angle_max()); + } else if (path.begins_with("constraint_angle_invert")) { + r_ret = get_constraint_angle_invert(); + } else if (path.begins_with("constraint_in_localspace")) { + r_ret = get_constraint_in_localspace(); + } else if (path.begins_with("additional_rotation")) { + r_ret = Math::rad2deg(get_additional_rotation()); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + r_ret = get_editor_draw_gizmo(); + } +#endif // TOOLS_ENABLED + + return true; +} + +void SkeletonModification2DLookAt::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::BOOL, "enable_constraint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (enable_constraint) { + p_list->push_back(PropertyInfo(Variant::FLOAT, "constraint_angle_min", PROPERTY_HINT_RANGE, "-360, 360, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::FLOAT, "constraint_angle_max", PROPERTY_HINT_RANGE, "-360, 360, 0.01", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, "constraint_angle_invert", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, "constraint_in_localspace", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } + p_list->push_back(PropertyInfo(Variant::FLOAT, "additional_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, "editor/draw_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif // TOOLS_ENABLED +} + +void SkeletonModification2DLookAt::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + + if (target_node_cache.is_null()) { + WARN_PRINT_ONCE("Target cache is out of date. Attempting to update..."); + update_target_cache(); + return; + } + + if (bone2d_node_cache.is_null() && !bone2d_node.is_empty()) { + update_bone2d_cache(); + WARN_PRINT_ONCE("Bone2D node cache is out of date. Attempting to update..."); + return; + } + + if (target_node_reference == nullptr) { + target_node_reference = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + } + if (!target_node_reference || !target_node_reference->is_inside_tree()) { + ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!"); + return; + } + if (bone_idx <= -1) { + ERR_PRINT_ONCE("Bone index is invalid. Cannot execute modification!"); + return; + } + + Bone2D *operation_bone = stack->skeleton->get_bone(bone_idx); + if (operation_bone == nullptr) { + ERR_PRINT_ONCE("bone_idx for modification does not point to a valid bone! Cannot execute modification"); + return; + } + + Transform2D operation_transform = operation_bone->get_global_transform(); + Transform2D target_trans = target_node_reference->get_global_transform(); + + // Look at the target! + operation_transform = operation_transform.looking_at(target_trans.get_origin()); + // Apply whatever scale it had prior to looking_at + operation_transform.set_scale(operation_bone->get_global_transform().get_scale()); + + // Account for the direction the bone faces in: + operation_transform.set_rotation(operation_transform.get_rotation() - operation_bone->get_bone_angle()); + + // Apply additional rotation + operation_transform.set_rotation(operation_transform.get_rotation() + additional_rotation); + + // Apply constraints in globalspace: + if (enable_constraint && !constraint_in_localspace) { + operation_transform.set_rotation(clamp_angle(operation_transform.get_rotation(), constraint_angle_min, constraint_angle_max, constraint_angle_invert)); + } + + // Convert from a global transform to a local transform via the Bone2D node + operation_bone->set_global_transform(operation_transform); + operation_transform = operation_bone->get_transform(); + + // Apply constraints in localspace: + if (enable_constraint && constraint_in_localspace) { + operation_transform.set_rotation(clamp_angle(operation_transform.get_rotation(), constraint_angle_min, constraint_angle_max, constraint_angle_invert)); + } + + // Set the local pose override, and to make sure child bones are also updated, set the transform of the bone. + stack->skeleton->set_bone_local_pose_override(bone_idx, operation_transform, stack->strength, true); + operation_bone->set_transform(operation_transform); +} + +void SkeletonModification2DLookAt::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack != nullptr) { + is_setup = true; + update_target_cache(); + update_bone2d_cache(); + } +} + +void SkeletonModification2DLookAt::_draw_editor_gizmo() { + if (!enabled || !is_setup) { + return; + } + + Bone2D *operation_bone = stack->skeleton->get_bone(bone_idx); + editor_draw_angle_constraints(operation_bone, constraint_angle_min, constraint_angle_max, + enable_constraint, constraint_in_localspace, constraint_angle_invert); +} + +void SkeletonModification2DLookAt::update_bone2d_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update Bone2D cache: modification is not properly setup!"); + return; + } + + bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(bone2d_node)) { + Node *node = stack->skeleton->get_node(bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update Bone2D cache: node is not in the scene tree!"); + bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("Error Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + + // Set this to null so we update it + target_node_reference = nullptr; + } + } + } +} + +void SkeletonModification2DLookAt::set_bone2d_node(const NodePath &p_target_node) { + bone2d_node = p_target_node; + update_bone2d_cache(); +} + +NodePath SkeletonModification2DLookAt::get_bone2d_node() const { + return bone2d_node; +} + +int SkeletonModification2DLookAt::get_bone_index() const { + return bone_idx; +} + +void SkeletonModification2DLookAt::set_bone_index(int p_bone_idx) { + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + bone_idx = p_bone_idx; + bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("Cannot verify the bone index for this modification..."); + bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("Cannot verify the bone index for this modification..."); + bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +void SkeletonModification2DLookAt::update_target_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + return; + } + + target_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(target_node)) { + Node *node = stack->skeleton->get_node(target_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update target cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update target cache: node is not in the scene tree!"); + target_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DLookAt::set_target_node(const NodePath &p_target_node) { + target_node = p_target_node; + update_target_cache(); +} + +NodePath SkeletonModification2DLookAt::get_target_node() const { + return target_node; +} + +float SkeletonModification2DLookAt::get_additional_rotation() const { + return additional_rotation; +} + +void SkeletonModification2DLookAt::set_additional_rotation(float p_rotation) { + additional_rotation = p_rotation; +} + +void SkeletonModification2DLookAt::set_enable_constraint(bool p_constraint) { + enable_constraint = p_constraint; + notify_property_list_changed(); +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DLookAt::get_enable_constraint() const { + return enable_constraint; +} + +void SkeletonModification2DLookAt::set_constraint_angle_min(float p_angle_min) { + constraint_angle_min = p_angle_min; +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +float SkeletonModification2DLookAt::get_constraint_angle_min() const { + return constraint_angle_min; +} + +void SkeletonModification2DLookAt::set_constraint_angle_max(float p_angle_max) { + constraint_angle_max = p_angle_max; +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +float SkeletonModification2DLookAt::get_constraint_angle_max() const { + return constraint_angle_max; +} + +void SkeletonModification2DLookAt::set_constraint_angle_invert(bool p_invert) { + constraint_angle_invert = p_invert; +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DLookAt::get_constraint_angle_invert() const { + return constraint_angle_invert; +} + +void SkeletonModification2DLookAt::set_constraint_in_localspace(bool p_constraint_in_localspace) { + constraint_in_localspace = p_constraint_in_localspace; +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DLookAt::get_constraint_in_localspace() const { + return constraint_in_localspace; +} + +void SkeletonModification2DLookAt::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_bone2d_node", "bone2d_nodepath"), &SkeletonModification2DLookAt::set_bone2d_node); + ClassDB::bind_method(D_METHOD("get_bone2d_node"), &SkeletonModification2DLookAt::get_bone2d_node); + ClassDB::bind_method(D_METHOD("set_bone_index", "bone_idx"), &SkeletonModification2DLookAt::set_bone_index); + ClassDB::bind_method(D_METHOD("get_bone_index"), &SkeletonModification2DLookAt::get_bone_index); + + ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DLookAt::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DLookAt::get_target_node); + + ClassDB::bind_method(D_METHOD("set_additional_rotation", "rotation"), &SkeletonModification2DLookAt::set_additional_rotation); + ClassDB::bind_method(D_METHOD("get_additional_rotation"), &SkeletonModification2DLookAt::get_additional_rotation); + + ClassDB::bind_method(D_METHOD("set_enable_constraint", "enable_constraint"), &SkeletonModification2DLookAt::set_enable_constraint); + ClassDB::bind_method(D_METHOD("get_enable_constraint"), &SkeletonModification2DLookAt::get_enable_constraint); + ClassDB::bind_method(D_METHOD("set_constraint_angle_min", "angle_min"), &SkeletonModification2DLookAt::set_constraint_angle_min); + ClassDB::bind_method(D_METHOD("get_constraint_angle_min"), &SkeletonModification2DLookAt::get_constraint_angle_min); + ClassDB::bind_method(D_METHOD("set_constraint_angle_max", "angle_max"), &SkeletonModification2DLookAt::set_constraint_angle_max); + ClassDB::bind_method(D_METHOD("get_constraint_angle_max"), &SkeletonModification2DLookAt::get_constraint_angle_max); + ClassDB::bind_method(D_METHOD("set_constraint_angle_invert", "invert"), &SkeletonModification2DLookAt::set_constraint_angle_invert); + ClassDB::bind_method(D_METHOD("get_constraint_angle_invert"), &SkeletonModification2DLookAt::get_constraint_angle_invert); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_index"), "set_bone_index", "get_bone_index"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D"), "set_bone2d_node", "get_bone2d_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node"); +} + +SkeletonModification2DLookAt::SkeletonModification2DLookAt() { + stack = nullptr; + is_setup = false; + bone_idx = -1; + additional_rotation = 0; + enable_constraint = false; + constraint_angle_min = 0; + constraint_angle_max = Math_PI * 2; + constraint_angle_invert = false; + enabled = true; + + editor_draw_gizmo = true; +} + +SkeletonModification2DLookAt::~SkeletonModification2DLookAt() { +} diff --git a/scene/resources/skeleton_modification_2d_lookat.h b/scene/resources/skeleton_modification_2d_lookat.h new file mode 100644 index 0000000000..6aff30b826 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_lookat.h @@ -0,0 +1,100 @@ +/*************************************************************************/ +/* skeleton_modification_2d_lookat.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DLOOKAT_H +#define SKELETONMODIFICATION2DLOOKAT_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DLookAt +/////////////////////////////////////// + +class SkeletonModification2DLookAt : public SkeletonModification2D { + GDCLASS(SkeletonModification2DLookAt, SkeletonModification2D); + +private: + int bone_idx = -1; + NodePath bone2d_node; + ObjectID bone2d_node_cache; + + NodePath target_node; + ObjectID target_node_cache; + Node2D *target_node_reference = nullptr; + + float additional_rotation = 0; + bool enable_constraint = false; + float constraint_angle_min = 0; + float constraint_angle_max = (2.0 * Math_PI); + bool constraint_angle_invert = false; + bool constraint_in_localspace = true; + + void update_bone2d_cache(); + void update_target_cache(); + +protected: + static void _bind_methods(); + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + void _draw_editor_gizmo() override; + + void set_bone2d_node(const NodePath &p_target_node); + NodePath get_bone2d_node() const; + void set_bone_index(int p_idx); + int get_bone_index() const; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + + void set_additional_rotation(float p_rotation); + float get_additional_rotation() const; + + void set_enable_constraint(bool p_constraint); + bool get_enable_constraint() const; + void set_constraint_angle_min(float p_angle_min); + float get_constraint_angle_min() const; + void set_constraint_angle_max(float p_angle_max); + float get_constraint_angle_max() const; + void set_constraint_angle_invert(bool p_invert); + bool get_constraint_angle_invert() const; + void set_constraint_in_localspace(bool p_constraint_in_localspace); + bool get_constraint_in_localspace() const; + + SkeletonModification2DLookAt(); + ~SkeletonModification2DLookAt(); +}; + +#endif // SKELETONMODIFICATION2DLOOKAT_H diff --git a/scene/resources/skeleton_modification_2d_physicalbones.cpp b/scene/resources/skeleton_modification_2d_physicalbones.cpp new file mode 100644 index 0000000000..9dedb93f36 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_physicalbones.cpp @@ -0,0 +1,297 @@ +/*************************************************************************/ +/* skeleton_modification_2d_physicalbones.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_physicalbones.h" +#include "scene/2d/physical_bone_2d.h" +#include "scene/2d/skeleton_2d.h" + +bool SkeletonModification2DPhysicalBones::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + +#ifdef TOOLS_ENABLED + // Exposes a way to fetch the PhysicalBone2D nodes from the Godot editor. + if (is_setup) { + if (Engine::get_singleton()->is_editor_hint()) { + if (path.begins_with("fetch_bones")) { + fetch_physical_bones(); + notify_property_list_changed(); + return true; + } + } + } +#endif //TOOLS_ENABLED + + if (path.begins_with("joint_")) { + int which = path.get_slicec('_', 1).to_int(); + String what = path.get_slicec('_', 2); + ERR_FAIL_INDEX_V(which, physical_bone_chain.size(), false); + + if (what == "nodepath") { + set_physical_bone_node(which, p_value); + } + return true; + } + return true; +} + +bool SkeletonModification2DPhysicalBones::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + if (path.begins_with("fetch_bones")) { + return true; // Do nothing! + } + } +#endif //TOOLS_ENABLED + + if (path.begins_with("joint_")) { + int which = path.get_slicec('_', 1).to_int(); + String what = path.get_slicec('_', 2); + ERR_FAIL_INDEX_V(which, physical_bone_chain.size(), false); + + if (what == "nodepath") { + r_ret = get_physical_bone_node(which); + } + return true; + } + return true; +} + +void SkeletonModification2DPhysicalBones::_get_property_list(List<PropertyInfo> *p_list) const { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, "fetch_bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif //TOOLS_ENABLED + + for (int i = 0; i < physical_bone_chain.size(); i++) { + String base_string = "joint_" + itos(i) + "_"; + + p_list->push_back(PropertyInfo(Variant::NODE_PATH, base_string + "nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicalBone2D", PROPERTY_USAGE_DEFAULT)); + } +} + +void SkeletonModification2DPhysicalBones::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + + if (_simulation_state_dirty) { + _update_simulation_state(); + } + + for (int i = 0; i < physical_bone_chain.size(); i++) { + PhysicalBone_Data2D bone_data = physical_bone_chain[i]; + if (bone_data.physical_bone_node_cache.is_null()) { + WARN_PRINT_ONCE("PhysicalBone2D cache " + itos(i) + " is out of date. Attempting to update..."); + _physical_bone_update_cache(i); + continue; + } + + PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(bone_data.physical_bone_node_cache)); + if (!physical_bone) { + ERR_PRINT_ONCE("PhysicalBone2D not found at index " + itos(i) + "!"); + return; + } + if (physical_bone->get_bone2d_index() < 0 || physical_bone->get_bone2d_index() > stack->skeleton->get_bone_count()) { + ERR_PRINT_ONCE("PhysicalBone2D at index " + itos(i) + " has invalid Bone2D!"); + return; + } + Bone2D *bone_2d = stack->skeleton->get_bone(physical_bone->get_bone2d_index()); + + if (physical_bone->get_simulate_physics() && !physical_bone->get_follow_bone_when_simulating()) { + bone_2d->set_global_transform(physical_bone->get_global_transform()); + stack->skeleton->set_bone_local_pose_override(physical_bone->get_bone2d_index(), bone_2d->get_transform(), stack->strength, true); + } + } +} + +void SkeletonModification2DPhysicalBones::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack) { + is_setup = true; + + if (stack->skeleton) { + for (int i = 0; i < physical_bone_chain.size(); i++) { + _physical_bone_update_cache(i); + } + } + } +} + +void SkeletonModification2DPhysicalBones::_physical_bone_update_cache(int p_joint_idx) { + ERR_FAIL_INDEX_MSG(p_joint_idx, physical_bone_chain.size(), "Cannot update PhysicalBone2D cache: joint index out of range!"); + if (!is_setup || !stack) { + if (!stack) { + ERR_PRINT_ONCE("Cannot update PhysicalBone2D cache: modification is not properly setup!"); + } + return; + } + + physical_bone_chain.write[p_joint_idx].physical_bone_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(physical_bone_chain[p_joint_idx].physical_bone_node)) { + Node *node = stack->skeleton->get_node(physical_bone_chain[p_joint_idx].physical_bone_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update Physical Bone2D " + itos(p_joint_idx) + " cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update Physical Bone2D " + itos(p_joint_idx) + " cache: node is not in scene tree!"); + physical_bone_chain.write[p_joint_idx].physical_bone_node_cache = node->get_instance_id(); + } + } + } +} + +int SkeletonModification2DPhysicalBones::get_physical_bone_chain_length() { + return physical_bone_chain.size(); +} + +void SkeletonModification2DPhysicalBones::set_physical_bone_chain_length(int p_length) { + ERR_FAIL_COND(p_length < 0); + physical_bone_chain.resize(p_length); + notify_property_list_changed(); +} + +void SkeletonModification2DPhysicalBones::fetch_physical_bones() { + ERR_FAIL_COND_MSG(!stack, "No modification stack found! Cannot fetch physical bones!"); + ERR_FAIL_COND_MSG(!stack->skeleton, "No skeleton found! Cannot fetch physical bones!"); + + physical_bone_chain.clear(); + + List<Node *> node_queue = List<Node *>(); + node_queue.push_back(stack->skeleton); + + while (node_queue.size() > 0) { + Node *node_to_process = node_queue[0]; + node_queue.pop_front(); + + if (node_to_process != nullptr) { + PhysicalBone2D *potential_bone = Object::cast_to<PhysicalBone2D>(node_to_process); + if (potential_bone) { + PhysicalBone_Data2D new_data = PhysicalBone_Data2D(); + new_data.physical_bone_node = stack->skeleton->get_path_to(potential_bone); + new_data.physical_bone_node_cache = potential_bone->get_instance_id(); + physical_bone_chain.push_back(new_data); + } + for (int i = 0; i < node_to_process->get_child_count(); i++) { + node_queue.push_back(node_to_process->get_child(i)); + } + } + } +} + +void SkeletonModification2DPhysicalBones::start_simulation(const TypedArray<StringName> &p_bones) { + _simulation_state_dirty = true; + _simulation_state_dirty_names = p_bones; + _simulation_state_dirty_process = true; + + if (is_setup) { + _update_simulation_state(); + } +} + +void SkeletonModification2DPhysicalBones::stop_simulation(const TypedArray<StringName> &p_bones) { + _simulation_state_dirty = true; + _simulation_state_dirty_names = p_bones; + _simulation_state_dirty_process = false; + + if (is_setup) { + _update_simulation_state(); + } +} + +void SkeletonModification2DPhysicalBones::_update_simulation_state() { + if (!_simulation_state_dirty) { + return; + } + _simulation_state_dirty = false; + + if (_simulation_state_dirty_names.size() <= 0) { + for (int i = 0; i < physical_bone_chain.size(); i++) { + PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(stack->skeleton->get_node(physical_bone_chain[i].physical_bone_node)); + if (!physical_bone) { + continue; + } + + physical_bone->set_simulate_physics(_simulation_state_dirty_process); + } + } else { + for (int i = 0; i < physical_bone_chain.size(); i++) { + PhysicalBone2D *physical_bone = Object::cast_to<PhysicalBone2D>(ObjectDB::get_instance(physical_bone_chain[i].physical_bone_node_cache)); + if (!physical_bone) { + continue; + } + if (_simulation_state_dirty_names.has(physical_bone->get_name())) { + physical_bone->set_simulate_physics(_simulation_state_dirty_process); + } + } + } +} + +void SkeletonModification2DPhysicalBones::set_physical_bone_node(int p_joint_idx, const NodePath &p_nodepath) { + ERR_FAIL_INDEX_MSG(p_joint_idx, physical_bone_chain.size(), "Joint index out of range!"); + physical_bone_chain.write[p_joint_idx].physical_bone_node = p_nodepath; + _physical_bone_update_cache(p_joint_idx); +} + +NodePath SkeletonModification2DPhysicalBones::get_physical_bone_node(int p_joint_idx) const { + ERR_FAIL_INDEX_V_MSG(p_joint_idx, physical_bone_chain.size(), NodePath(), "Joint index out of range!"); + return physical_bone_chain[p_joint_idx].physical_bone_node; +} + +void SkeletonModification2DPhysicalBones::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_physical_bone_chain_length", "length"), &SkeletonModification2DPhysicalBones::set_physical_bone_chain_length); + ClassDB::bind_method(D_METHOD("get_physical_bone_chain_length"), &SkeletonModification2DPhysicalBones::get_physical_bone_chain_length); + + ClassDB::bind_method(D_METHOD("set_physical_bone_node", "joint_idx", "physicalbone2d_node"), &SkeletonModification2DPhysicalBones::set_physical_bone_node); + ClassDB::bind_method(D_METHOD("get_physical_bone_node", "joint_idx"), &SkeletonModification2DPhysicalBones::get_physical_bone_node); + + ClassDB::bind_method(D_METHOD("fetch_physical_bones"), &SkeletonModification2DPhysicalBones::fetch_physical_bones); + ClassDB::bind_method(D_METHOD("start_simulation", "bones"), &SkeletonModification2DPhysicalBones::start_simulation, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("stop_simulation", "bones"), &SkeletonModification2DPhysicalBones::stop_simulation, DEFVAL(Array())); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "physical_bone_chain_length", PROPERTY_HINT_RANGE, "0,100,1"), "set_physical_bone_chain_length", "get_physical_bone_chain_length"); +} + +SkeletonModification2DPhysicalBones::SkeletonModification2DPhysicalBones() { + stack = nullptr; + is_setup = false; + physical_bone_chain = Vector<PhysicalBone_Data2D>(); + enabled = true; + editor_draw_gizmo = false; // Nothing to really show in a gizmo right now. +} + +SkeletonModification2DPhysicalBones::~SkeletonModification2DPhysicalBones() { +} diff --git a/scene/resources/skeleton_modification_2d_physicalbones.h b/scene/resources/skeleton_modification_2d_physicalbones.h new file mode 100644 index 0000000000..cdf6a5f570 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_physicalbones.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* skeleton_modification_2d_physicalbones.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DPHYSICALBONES_H +#define SKELETONMODIFICATION2DPHYSICALBONES_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DJIGGLE +/////////////////////////////////////// + +class SkeletonModification2DPhysicalBones : public SkeletonModification2D { + GDCLASS(SkeletonModification2DPhysicalBones, SkeletonModification2D); + +private: + struct PhysicalBone_Data2D { + NodePath physical_bone_node; + ObjectID physical_bone_node_cache; + }; + Vector<PhysicalBone_Data2D> physical_bone_chain; + + void _physical_bone_update_cache(int p_joint_idx); + + bool _simulation_state_dirty = false; + TypedArray<StringName> _simulation_state_dirty_names; + bool _simulation_state_dirty_process; + void _update_simulation_state(); + +protected: + static void _bind_methods(); + bool _get(const StringName &p_path, Variant &r_ret) const; + bool _set(const StringName &p_path, const Variant &p_value); + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + + int get_physical_bone_chain_length(); + void set_physical_bone_chain_length(int p_new_length); + + void set_physical_bone_node(int p_joint_idx, const NodePath &p_path); + NodePath get_physical_bone_node(int p_joint_idx) const; + + void fetch_physical_bones(); + void start_simulation(const TypedArray<StringName> &p_bones); + void stop_simulation(const TypedArray<StringName> &p_bones); + + SkeletonModification2DPhysicalBones(); + ~SkeletonModification2DPhysicalBones(); +}; + +#endif // SKELETONMODIFICATION2DPHYSICALBONES_H diff --git a/scene/resources/skeleton_modification_2d_stackholder.cpp b/scene/resources/skeleton_modification_2d_stackholder.cpp new file mode 100644 index 0000000000..9436092cd9 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_stackholder.cpp @@ -0,0 +1,131 @@ +/*************************************************************************/ +/* skeleton_modification_2d_stackholder.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_stackholder.h" +#include "scene/2d/skeleton_2d.h" + +bool SkeletonModification2DStackHolder::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path == "held_modification_stack") { + set_held_modification_stack(p_value); + } + +#ifdef TOOLS_ENABLED + if (path == "editor/draw_gizmo") { + set_editor_draw_gizmo(p_value); + } +#endif // TOOLS_ENABLED + + return true; +} + +bool SkeletonModification2DStackHolder::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path == "held_modification_stack") { + r_ret = get_held_modification_stack(); + } + +#ifdef TOOLS_ENABLED + if (path == "editor/draw_gizmo") { + r_ret = get_editor_draw_gizmo(); + } +#endif // TOOLS_ENABLED + + return true; +} + +void SkeletonModification2DStackHolder::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::OBJECT, "held_modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, "editor/draw_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif // TOOLS_ENABLED +} + +void SkeletonModification2DStackHolder::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + + if (held_modification_stack.is_valid()) { + held_modification_stack->execute(p_delta, execution_mode); + } +} + +void SkeletonModification2DStackHolder::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack != nullptr) { + is_setup = true; + + if (held_modification_stack.is_valid()) { + held_modification_stack->set_skeleton(stack->get_skeleton()); + held_modification_stack->setup(); + } + } +} + +void SkeletonModification2DStackHolder::_draw_editor_gizmo() { + if (stack) { + if (held_modification_stack.is_valid()) { + held_modification_stack->draw_editor_gizmos(); + } + } +} + +void SkeletonModification2DStackHolder::set_held_modification_stack(Ref<SkeletonModificationStack2D> p_held_stack) { + held_modification_stack = p_held_stack; + + if (is_setup && held_modification_stack.is_valid()) { + held_modification_stack->set_skeleton(stack->get_skeleton()); + held_modification_stack->setup(); + } +} + +Ref<SkeletonModificationStack2D> SkeletonModification2DStackHolder::get_held_modification_stack() const { + return held_modification_stack; +} + +void SkeletonModification2DStackHolder::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_held_modification_stack", "held_modification_stack"), &SkeletonModification2DStackHolder::set_held_modification_stack); + ClassDB::bind_method(D_METHOD("get_held_modification_stack"), &SkeletonModification2DStackHolder::get_held_modification_stack); +} + +SkeletonModification2DStackHolder::SkeletonModification2DStackHolder() { + stack = nullptr; + is_setup = false; + enabled = true; +} + +SkeletonModification2DStackHolder::~SkeletonModification2DStackHolder() { +} diff --git a/scene/2d/y_sort.h b/scene/resources/skeleton_modification_2d_stackholder.h index 7d36ee3391..9cc38e3942 100644 --- a/scene/2d/y_sort.h +++ b/scene/resources/skeleton_modification_2d_stackholder.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* y_sort.h */ +/* skeleton_modification_2d_stackholder.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,37 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef Y_SORT_H -#define Y_SORT_H +#ifndef SKELETONMODIFICATION2DSTACKHOLDER_H +#define SKELETONMODIFICATION2DSTACKHOLDER_H -#include "scene/2d/node_2d.h" +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" -class YSort : public Node2D { - GDCLASS(YSort, Node2D); - bool sort_enabled = true; +/////////////////////////////////////// +// SkeletonModification2DJIGGLE +/////////////////////////////////////// + +class SkeletonModification2DStackHolder : public SkeletonModification2D { + GDCLASS(SkeletonModification2DStackHolder, SkeletonModification2D); + +protected: static void _bind_methods(); + bool _get(const StringName &p_path, Variant &r_ret) const; + bool _set(const StringName &p_path, const Variant &p_value); + void _get_property_list(List<PropertyInfo> *p_list) const; public: - void set_sort_enabled(bool p_enabled); - bool is_sort_enabled() const; - YSort(); + Ref<SkeletonModificationStack2D> held_modification_stack; + + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + void _draw_editor_gizmo() override; + + void set_held_modification_stack(Ref<SkeletonModificationStack2D> p_held_stack); + Ref<SkeletonModificationStack2D> get_held_modification_stack() const; + + SkeletonModification2DStackHolder(); + ~SkeletonModification2DStackHolder(); }; -#endif // Y_SORT_H +#endif // SKELETONMODIFICATION2DSTACKHOLDER_H diff --git a/scene/resources/skeleton_modification_2d_twoboneik.cpp b/scene/resources/skeleton_modification_2d_twoboneik.cpp new file mode 100644 index 0000000000..0a91290015 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_twoboneik.cpp @@ -0,0 +1,481 @@ +/*************************************************************************/ +/* skeleton_modification_2d_twoboneik.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_2d_twoboneik.h" +#include "scene/2d/skeleton_2d.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif // TOOLS_ENABLED + +bool SkeletonModification2DTwoBoneIK::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path == "joint_one_bone_idx") { + set_joint_one_bone_idx(p_value); + } else if (path == "joint_one_bone2d_node") { + set_joint_one_bone2d_node(p_value); + } else if (path == "joint_two_bone_idx") { + set_joint_two_bone_idx(p_value); + } else if (path == "joint_two_bone2d_node") { + set_joint_two_bone2d_node(p_value); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + set_editor_draw_gizmo(p_value); + } else if (path.begins_with("editor/draw_min_max")) { + set_editor_draw_min_max(p_value); + } +#endif // TOOLS_ENABLED + + return true; +} + +bool SkeletonModification2DTwoBoneIK::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path == "joint_one_bone_idx") { + r_ret = get_joint_one_bone_idx(); + } else if (path == "joint_one_bone2d_node") { + r_ret = get_joint_one_bone2d_node(); + } else if (path == "joint_two_bone_idx") { + r_ret = get_joint_two_bone_idx(); + } else if (path == "joint_two_bone2d_node") { + r_ret = get_joint_two_bone2d_node(); + } + +#ifdef TOOLS_ENABLED + if (path.begins_with("editor/draw_gizmo")) { + r_ret = get_editor_draw_gizmo(); + } else if (path.begins_with("editor/draw_min_max")) { + r_ret = get_editor_draw_min_max(); + } +#endif // TOOLS_ENABLED + + return true; +} + +void SkeletonModification2DTwoBoneIK::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::INT, "joint_one_bone_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::NODE_PATH, "joint_one_bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT)); + + p_list->push_back(PropertyInfo(Variant::INT, "joint_two_bone_idx", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::NODE_PATH, "joint_two_bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT)); + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + p_list->push_back(PropertyInfo(Variant::BOOL, "editor/draw_gizmo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + p_list->push_back(PropertyInfo(Variant::BOOL, "editor/draw_min_max", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + } +#endif // TOOLS_ENABLED +} + +void SkeletonModification2DTwoBoneIK::_execute(float p_delta) { + ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr, + "Modification is not setup and therefore cannot execute!"); + if (!enabled) { + return; + } + + if (target_node_cache.is_null()) { + WARN_PRINT_ONCE("Target cache is out of date. Attempting to update..."); + update_target_cache(); + return; + } + + if (joint_one_bone2d_node_cache.is_null() && !joint_one_bone2d_node.is_empty()) { + WARN_PRINT_ONCE("Joint one Bone2D node cache is out of date. Attempting to update..."); + update_joint_one_bone2d_cache(); + } + if (joint_two_bone2d_node_cache.is_null() && !joint_two_bone2d_node.is_empty()) { + WARN_PRINT_ONCE("Joint two Bone2D node cache is out of date. Attempting to update..."); + update_joint_two_bone2d_cache(); + } + + Node2D *target = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + if (!target || !target->is_inside_tree()) { + ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!"); + return; + } + + Bone2D *joint_one_bone = stack->skeleton->get_bone(joint_one_bone_idx); + if (joint_one_bone == nullptr) { + ERR_PRINT_ONCE("Joint one bone_idx does not point to a valid bone! Cannot execute modification!"); + return; + } + + Bone2D *joint_two_bone = stack->skeleton->get_bone(joint_two_bone_idx); + if (joint_two_bone == nullptr) { + ERR_PRINT_ONCE("Joint two bone_idx does not point to a valid bone! Cannot execute modification!"); + return; + } + + // Adopted from the links below: + // http://theorangeduck.com/page/simple-two-joint + // https://www.alanzucconi.com/2018/05/02/ik-2d-2/ + // With modifications by TwistedTwigleg + Vector2 target_difference = target->get_global_transform().get_origin() - joint_one_bone->get_global_transform().get_origin(); + float joint_one_to_target = target_difference.length(); + float angle_atan = Math::atan2(target_difference.y, target_difference.x); + + float bone_one_length = joint_one_bone->get_length() * MIN(joint_one_bone->get_global_scale().x, joint_one_bone->get_global_scale().y); + float bone_two_length = joint_two_bone->get_length() * MIN(joint_two_bone->get_global_scale().x, joint_two_bone->get_global_scale().y); + bool override_angles_due_to_out_of_range = false; + + if (joint_one_to_target < target_minimum_distance) { + joint_one_to_target = target_minimum_distance; + } + if (joint_one_to_target > target_maximum_distance && target_maximum_distance > 0.0) { + joint_one_to_target = target_maximum_distance; + } + + if (bone_one_length + bone_two_length < joint_one_to_target) { + override_angles_due_to_out_of_range = true; + } + + if (!override_angles_due_to_out_of_range) { + float angle_0 = Math::acos(((joint_one_to_target * joint_one_to_target) + (bone_one_length * bone_one_length) - (bone_two_length * bone_two_length)) / (2.0 * joint_one_to_target * bone_one_length)); + float angle_1 = Math::acos(((bone_two_length * bone_two_length) + (bone_one_length * bone_one_length) - (joint_one_to_target * joint_one_to_target)) / (2.0 * bone_two_length * bone_one_length)); + + if (flip_bend_direction) { + angle_0 = -angle_0; + angle_1 = -angle_1; + } + + if (isnan(angle_0) || isnan(angle_1)) { + // We cannot solve for this angle! Do nothing to avoid setting the rotation (and scale) to NaN. + } else { + joint_one_bone->set_global_rotation(angle_atan - angle_0 - joint_one_bone->get_bone_angle()); + joint_two_bone->set_rotation(-Math_PI - angle_1 - joint_two_bone->get_bone_angle() + joint_one_bone->get_bone_angle()); + } + } else { + joint_one_bone->set_global_rotation(angle_atan - joint_one_bone->get_bone_angle()); + joint_two_bone->set_global_rotation(angle_atan - joint_two_bone->get_bone_angle()); + } + + stack->skeleton->set_bone_local_pose_override(joint_one_bone_idx, joint_one_bone->get_transform(), stack->strength, true); + stack->skeleton->set_bone_local_pose_override(joint_two_bone_idx, joint_two_bone->get_transform(), stack->strength, true); +} + +void SkeletonModification2DTwoBoneIK::_setup_modification(SkeletonModificationStack2D *p_stack) { + stack = p_stack; + + if (stack) { + is_setup = true; + update_target_cache(); + update_joint_one_bone2d_cache(); + update_joint_two_bone2d_cache(); + } +} + +void SkeletonModification2DTwoBoneIK::_draw_editor_gizmo() { + if (!enabled || !is_setup) { + return; + } + + Bone2D *operation_bone_one = stack->skeleton->get_bone(joint_one_bone_idx); + if (!operation_bone_one) { + return; + } + stack->skeleton->draw_set_transform( + stack->skeleton->get_global_transform().affine_inverse().xform(operation_bone_one->get_global_position()), + operation_bone_one->get_global_rotation() - stack->skeleton->get_global_rotation()); + + Color bone_ik_color = Color(1.0, 0.65, 0.0, 0.4); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); + } +#endif // TOOLS_ENABLED + + if (flip_bend_direction) { + float angle = -(Math_PI * 0.5) + operation_bone_one->get_bone_angle(); + stack->skeleton->draw_line(Vector2(0, 0), Vector2(Math::cos(angle), sin(angle)) * (operation_bone_one->get_length() * 0.5), bone_ik_color, 2.0); + } else { + float angle = (Math_PI * 0.5) + operation_bone_one->get_bone_angle(); + stack->skeleton->draw_line(Vector2(0, 0), Vector2(Math::cos(angle), sin(angle)) * (operation_bone_one->get_length() * 0.5), bone_ik_color, 2.0); + } + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + if (editor_draw_min_max) { + if (target_maximum_distance != 0.0 || target_minimum_distance != 0.0) { + Vector2 target_direction = Vector2(0, 1); + if (target_node_cache.is_valid()) { + stack->skeleton->draw_set_transform(Vector2(0, 0), 0.0); + Node2D *target = Object::cast_to<Node2D>(ObjectDB::get_instance(target_node_cache)); + target_direction = operation_bone_one->get_global_position().direction_to(target->get_global_position()); + } + + stack->skeleton->draw_circle(target_direction * target_minimum_distance, 8, bone_ik_color); + stack->skeleton->draw_circle(target_direction * target_maximum_distance, 8, bone_ik_color); + stack->skeleton->draw_line(target_direction * target_minimum_distance, target_direction * target_maximum_distance, bone_ik_color, 2.0); + } + } + } +#endif // TOOLS_ENABLED +} + +void SkeletonModification2DTwoBoneIK::update_target_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + return; + } + + target_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(target_node)) { + Node *node = stack->skeleton->get_node(target_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update target cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update target cache: node is not in the scene tree!"); + target_node_cache = node->get_instance_id(); + } + } + } +} + +void SkeletonModification2DTwoBoneIK::update_joint_one_bone2d_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update joint one Bone2D cache: modification is not properly setup!"); + return; + } + + joint_one_bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(joint_one_bone2d_node)) { + Node *node = stack->skeleton->get_node(joint_one_bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update update joint one Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update update joint one Bone2D cache: node is not in the scene tree!"); + joint_one_bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + joint_one_bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("update joint one Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + } + } + } +} + +void SkeletonModification2DTwoBoneIK::update_joint_two_bone2d_cache() { + if (!is_setup || !stack) { + ERR_PRINT_ONCE("Cannot update joint two Bone2D cache: modification is not properly setup!"); + return; + } + + joint_two_bone2d_node_cache = ObjectID(); + if (stack->skeleton) { + if (stack->skeleton->is_inside_tree()) { + if (stack->skeleton->has_node(joint_two_bone2d_node)) { + Node *node = stack->skeleton->get_node(joint_two_bone2d_node); + ERR_FAIL_COND_MSG(!node || stack->skeleton == node, + "Cannot update update joint two Bone2D cache: node is this modification's skeleton or cannot be found!"); + ERR_FAIL_COND_MSG(!node->is_inside_tree(), + "Cannot update update joint two Bone2D cache: node is not in scene tree!"); + joint_two_bone2d_node_cache = node->get_instance_id(); + + Bone2D *bone = Object::cast_to<Bone2D>(node); + if (bone) { + joint_two_bone_idx = bone->get_index_in_skeleton(); + } else { + ERR_FAIL_MSG("update joint two Bone2D cache: Nodepath to Bone2D is not a Bone2D node!"); + } + } + } + } +} + +void SkeletonModification2DTwoBoneIK::set_target_node(const NodePath &p_target_node) { + target_node = p_target_node; + update_target_cache(); +} + +NodePath SkeletonModification2DTwoBoneIK::get_target_node() const { + return target_node; +} + +void SkeletonModification2DTwoBoneIK::set_joint_one_bone2d_node(const NodePath &p_target_node) { + joint_one_bone2d_node = p_target_node; + update_joint_one_bone2d_cache(); + notify_property_list_changed(); +} + +void SkeletonModification2DTwoBoneIK::set_target_minimum_distance(float p_distance) { + ERR_FAIL_COND_MSG(p_distance < 0, "Target minimum distance cannot be less than zero!"); + target_minimum_distance = p_distance; +} + +float SkeletonModification2DTwoBoneIK::get_target_minimum_distance() const { + return target_minimum_distance; +} + +void SkeletonModification2DTwoBoneIK::set_target_maximum_distance(float p_distance) { + ERR_FAIL_COND_MSG(p_distance < 0, "Target maximum distance cannot be less than zero!"); + target_maximum_distance = p_distance; +} + +float SkeletonModification2DTwoBoneIK::get_target_maximum_distance() const { + return target_maximum_distance; +} + +void SkeletonModification2DTwoBoneIK::set_flip_bend_direction(bool p_flip_direction) { + flip_bend_direction = p_flip_direction; + +#ifdef TOOLS_ENABLED + if (stack && is_setup) { + stack->set_editor_gizmos_dirty(true); + } +#endif // TOOLS_ENABLED +} + +bool SkeletonModification2DTwoBoneIK::get_flip_bend_direction() const { + return flip_bend_direction; +} + +NodePath SkeletonModification2DTwoBoneIK::get_joint_one_bone2d_node() const { + return joint_one_bone2d_node; +} + +void SkeletonModification2DTwoBoneIK::set_joint_two_bone2d_node(const NodePath &p_target_node) { + joint_two_bone2d_node = p_target_node; + update_joint_two_bone2d_cache(); + notify_property_list_changed(); +} + +NodePath SkeletonModification2DTwoBoneIK::get_joint_two_bone2d_node() const { + return joint_two_bone2d_node; +} + +void SkeletonModification2DTwoBoneIK::set_joint_one_bone_idx(int p_bone_idx) { + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + joint_one_bone_idx = p_bone_idx; + joint_one_bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + joint_one_bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint one..."); + joint_one_bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint one..."); + joint_one_bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +int SkeletonModification2DTwoBoneIK::get_joint_one_bone_idx() const { + return joint_one_bone_idx; +} + +void SkeletonModification2DTwoBoneIK::set_joint_two_bone_idx(int p_bone_idx) { + ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!"); + + if (is_setup) { + if (stack->skeleton) { + ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!"); + joint_two_bone_idx = p_bone_idx; + joint_two_bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id(); + joint_two_bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx)); + } else { + WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint two..."); + joint_two_bone_idx = p_bone_idx; + } + } else { + WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint two..."); + joint_two_bone_idx = p_bone_idx; + } + + notify_property_list_changed(); +} + +int SkeletonModification2DTwoBoneIK::get_joint_two_bone_idx() const { + return joint_two_bone_idx; +} + +#ifdef TOOLS_ENABLED +void SkeletonModification2DTwoBoneIK::set_editor_draw_min_max(bool p_draw) { + editor_draw_min_max = p_draw; +} + +bool SkeletonModification2DTwoBoneIK::get_editor_draw_min_max() const { + return editor_draw_min_max; +} +#endif // TOOLS_ENABLED + +void SkeletonModification2DTwoBoneIK::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DTwoBoneIK::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DTwoBoneIK::get_target_node); + + ClassDB::bind_method(D_METHOD("set_target_minimum_distance", "minimum_distance"), &SkeletonModification2DTwoBoneIK::set_target_minimum_distance); + ClassDB::bind_method(D_METHOD("get_target_minimum_distance"), &SkeletonModification2DTwoBoneIK::get_target_minimum_distance); + ClassDB::bind_method(D_METHOD("set_target_maximum_distance", "maximum_distance"), &SkeletonModification2DTwoBoneIK::set_target_maximum_distance); + ClassDB::bind_method(D_METHOD("get_target_maximum_distance"), &SkeletonModification2DTwoBoneIK::get_target_maximum_distance); + ClassDB::bind_method(D_METHOD("set_flip_bend_direction", "flip_direction"), &SkeletonModification2DTwoBoneIK::set_flip_bend_direction); + ClassDB::bind_method(D_METHOD("get_flip_bend_direction"), &SkeletonModification2DTwoBoneIK::get_flip_bend_direction); + + ClassDB::bind_method(D_METHOD("set_joint_one_bone2d_node", "bone2d_node"), &SkeletonModification2DTwoBoneIK::set_joint_one_bone2d_node); + ClassDB::bind_method(D_METHOD("get_joint_one_bone2d_node"), &SkeletonModification2DTwoBoneIK::get_joint_one_bone2d_node); + ClassDB::bind_method(D_METHOD("set_joint_one_bone_idx", "bone_idx"), &SkeletonModification2DTwoBoneIK::set_joint_one_bone_idx); + ClassDB::bind_method(D_METHOD("get_joint_one_bone_idx"), &SkeletonModification2DTwoBoneIK::get_joint_one_bone_idx); + + ClassDB::bind_method(D_METHOD("set_joint_two_bone2d_node", "bone2d_node"), &SkeletonModification2DTwoBoneIK::set_joint_two_bone2d_node); + ClassDB::bind_method(D_METHOD("get_joint_two_bone2d_node"), &SkeletonModification2DTwoBoneIK::get_joint_two_bone2d_node); + ClassDB::bind_method(D_METHOD("set_joint_two_bone_idx", "bone_idx"), &SkeletonModification2DTwoBoneIK::set_joint_two_bone_idx); + ClassDB::bind_method(D_METHOD("get_joint_two_bone_idx"), &SkeletonModification2DTwoBoneIK::get_joint_two_bone_idx); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_minimum_distance", PROPERTY_HINT_RANGE, "0, 100000000, 0.01"), "set_target_minimum_distance", "get_target_minimum_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_maximum_distance", PROPERTY_HINT_NONE, "0, 100000000, 0.01"), "set_target_maximum_distance", "get_target_maximum_distance"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_bend_direction", PROPERTY_HINT_NONE, ""), "set_flip_bend_direction", "get_flip_bend_direction"); + ADD_GROUP("", ""); +} + +SkeletonModification2DTwoBoneIK::SkeletonModification2DTwoBoneIK() { + stack = nullptr; + is_setup = false; + enabled = true; + editor_draw_gizmo = true; +} + +SkeletonModification2DTwoBoneIK::~SkeletonModification2DTwoBoneIK() { +} diff --git a/scene/resources/skeleton_modification_2d_twoboneik.h b/scene/resources/skeleton_modification_2d_twoboneik.h new file mode 100644 index 0000000000..c7e545a488 --- /dev/null +++ b/scene/resources/skeleton_modification_2d_twoboneik.h @@ -0,0 +1,107 @@ +/*************************************************************************/ +/* skeleton_modification_2d_twoboneik.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATION2DTWOBONEIK_H +#define SKELETONMODIFICATION2DTWOBONEIK_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModification2DJIGGLE +/////////////////////////////////////// + +class SkeletonModification2DTwoBoneIK : public SkeletonModification2D { + GDCLASS(SkeletonModification2DTwoBoneIK, SkeletonModification2D); + +private: + NodePath target_node; + ObjectID target_node_cache; + float target_minimum_distance = 0; + float target_maximum_distance = 0; + bool flip_bend_direction = false; + + NodePath joint_one_bone2d_node; + ObjectID joint_one_bone2d_node_cache; + int joint_one_bone_idx = -1; + + NodePath joint_two_bone2d_node; + ObjectID joint_two_bone2d_node_cache; + int joint_two_bone_idx = -1; + +#ifdef TOOLS_ENABLED + bool editor_draw_min_max = false; +#endif // TOOLS_ENABLED + + void update_target_cache(); + void update_joint_one_bone2d_cache(); + void update_joint_two_bone2d_cache(); + +protected: + static void _bind_methods(); + bool _get(const StringName &p_path, Variant &r_ret) const; + bool _set(const StringName &p_path, const Variant &p_value); + void _get_property_list(List<PropertyInfo> *p_list) const; + +public: + void _execute(float p_delta) override; + void _setup_modification(SkeletonModificationStack2D *p_stack) override; + void _draw_editor_gizmo() override; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + + void set_target_minimum_distance(float p_minimum_distance); + float get_target_minimum_distance() const; + void set_target_maximum_distance(float p_maximum_distance); + float get_target_maximum_distance() const; + void set_flip_bend_direction(bool p_flip_direction); + bool get_flip_bend_direction() const; + + void set_joint_one_bone2d_node(const NodePath &p_node); + NodePath get_joint_one_bone2d_node() const; + void set_joint_one_bone_idx(int p_bone_idx); + int get_joint_one_bone_idx() const; + + void set_joint_two_bone2d_node(const NodePath &p_node); + NodePath get_joint_two_bone2d_node() const; + void set_joint_two_bone_idx(int p_bone_idx); + int get_joint_two_bone_idx() const; + +#ifdef TOOLS_ENABLED + void set_editor_draw_min_max(bool p_draw); + bool get_editor_draw_min_max() const; +#endif // TOOLS_ENABLED + + SkeletonModification2DTwoBoneIK(); + ~SkeletonModification2DTwoBoneIK(); +}; + +#endif // SKELETONMODIFICATION2DTWOBONEIK_H diff --git a/scene/resources/skeleton_modification_stack_2d.cpp b/scene/resources/skeleton_modification_stack_2d.cpp new file mode 100644 index 0000000000..d12ec4add3 --- /dev/null +++ b/scene/resources/skeleton_modification_stack_2d.cpp @@ -0,0 +1,267 @@ +/*************************************************************************/ +/* skeleton_modification_stack_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_modification_stack_2d.h" +#include "scene/2d/skeleton_2d.h" + +void SkeletonModificationStack2D::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < modifications.size(); i++) { + p_list->push_back( + PropertyInfo(Variant::OBJECT, "modifications/" + itos(i), + PROPERTY_HINT_RESOURCE_TYPE, + "SkeletonModification2D", + PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + } +} + +bool SkeletonModificationStack2D::_set(const StringName &p_path, const Variant &p_value) { + String path = p_path; + + if (path.begins_with("modifications/")) { + int mod_idx = path.get_slicec('/', 1).to_int(); + set_modification(mod_idx, p_value); + return true; + } + return true; +} + +bool SkeletonModificationStack2D::_get(const StringName &p_path, Variant &r_ret) const { + String path = p_path; + + if (path.begins_with("modifications/")) { + int mod_idx = path.get_slicec('/', 1).to_int(); + r_ret = get_modification(mod_idx); + return true; + } + return true; +} + +void SkeletonModificationStack2D::setup() { + if (is_setup) { + return; + } + + if (skeleton != nullptr) { + is_setup = true; + for (int i = 0; i < modifications.size(); i++) { + if (!modifications[i].is_valid()) { + continue; + } + modifications.get(i)->_setup_modification(this); + } + +#ifdef TOOLS_ENABLED + set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED + + } else { + WARN_PRINT("Cannot setup SkeletonModificationStack2D: no Skeleton2D set!"); + } +} + +void SkeletonModificationStack2D::execute(float p_delta, int p_execution_mode) { + ERR_FAIL_COND_MSG(!is_setup || skeleton == nullptr || is_queued_for_deletion(), + "Modification stack is not properly setup and therefore cannot execute!"); + + if (!skeleton->is_inside_tree()) { + ERR_PRINT_ONCE("Skeleton is not inside SceneTree! Cannot execute modification!"); + return; + } + + if (!enabled) { + return; + } + + for (int i = 0; i < modifications.size(); i++) { + if (!modifications[i].is_valid()) { + continue; + } + + if (modifications[i]->get_execution_mode() == p_execution_mode) { + modifications.get(i)->_execute(p_delta); + } + } +} + +void SkeletonModificationStack2D::draw_editor_gizmos() { + if (!is_setup) { + return; + } + + if (editor_gizmo_dirty) { + for (int i = 0; i < modifications.size(); i++) { + if (!modifications[i].is_valid()) { + continue; + } + + if (modifications[i]->editor_draw_gizmo) { + modifications.get(i)->_draw_editor_gizmo(); + } + } + skeleton->draw_set_transform(Vector2(0, 0)); + editor_gizmo_dirty = false; + } +} + +void SkeletonModificationStack2D::set_editor_gizmos_dirty(bool p_dirty) { + if (!is_setup) { + return; + } + + if (!editor_gizmo_dirty && p_dirty) { + editor_gizmo_dirty = p_dirty; + if (skeleton) { + skeleton->update(); + } + } else { + editor_gizmo_dirty = p_dirty; + } +} + +void SkeletonModificationStack2D::enable_all_modifications(bool p_enabled) { + for (int i = 0; i < modifications.size(); i++) { + if (!modifications[i].is_valid()) { + continue; + } + modifications.get(i)->set_enabled(p_enabled); + } +} + +Ref<SkeletonModification2D> SkeletonModificationStack2D::get_modification(int p_mod_idx) const { + ERR_FAIL_INDEX_V(p_mod_idx, modifications.size(), nullptr); + return modifications[p_mod_idx]; +} + +void SkeletonModificationStack2D::add_modification(Ref<SkeletonModification2D> p_mod) { + p_mod->_setup_modification(this); + modifications.push_back(p_mod); + +#ifdef TOOLS_ENABLED + set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED +} + +void SkeletonModificationStack2D::delete_modification(int p_mod_idx) { + ERR_FAIL_INDEX(p_mod_idx, modifications.size()); + modifications.remove(p_mod_idx); + +#ifdef TOOLS_ENABLED + set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED +} + +void SkeletonModificationStack2D::set_modification(int p_mod_idx, Ref<SkeletonModification2D> p_mod) { + ERR_FAIL_INDEX(p_mod_idx, modifications.size()); + + if (p_mod == nullptr) { + modifications.insert(p_mod_idx, nullptr); + } else { + p_mod->_setup_modification(this); + modifications.insert(p_mod_idx, p_mod); + } + +#ifdef TOOLS_ENABLED + set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED +} + +void SkeletonModificationStack2D::set_modification_count(int p_count) { + modifications.resize(p_count); + notify_property_list_changed(); + +#ifdef TOOLS_ENABLED + set_editor_gizmos_dirty(true); +#endif // TOOLS_ENABLED +} + +int SkeletonModificationStack2D::get_modification_count() const { + return modifications.size(); +} + +void SkeletonModificationStack2D::set_skeleton(Skeleton2D *p_skeleton) { + skeleton = p_skeleton; +} + +Skeleton2D *SkeletonModificationStack2D::get_skeleton() const { + return skeleton; +} + +bool SkeletonModificationStack2D::get_is_setup() const { + return is_setup; +} + +void SkeletonModificationStack2D::set_enabled(bool p_enabled) { + enabled = p_enabled; +} + +bool SkeletonModificationStack2D::get_enabled() const { + return enabled; +} + +void SkeletonModificationStack2D::set_strength(float p_strength) { + ERR_FAIL_COND_MSG(p_strength < 0, "Strength cannot be less than zero!"); + ERR_FAIL_COND_MSG(p_strength > 1, "Strength cannot be more than one!"); + strength = p_strength; +} + +float SkeletonModificationStack2D::get_strength() const { + return strength; +} + +void SkeletonModificationStack2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("setup"), &SkeletonModificationStack2D::setup); + ClassDB::bind_method(D_METHOD("execute", "delta", "execution_mode"), &SkeletonModificationStack2D::execute); + + ClassDB::bind_method(D_METHOD("enable_all_modifications", "enabled"), &SkeletonModificationStack2D::enable_all_modifications); + ClassDB::bind_method(D_METHOD("get_modification", "mod_idx"), &SkeletonModificationStack2D::get_modification); + ClassDB::bind_method(D_METHOD("add_modification", "modification"), &SkeletonModificationStack2D::add_modification); + ClassDB::bind_method(D_METHOD("delete_modification", "mod_idx"), &SkeletonModificationStack2D::delete_modification); + ClassDB::bind_method(D_METHOD("set_modification", "mod_idx", "modification"), &SkeletonModificationStack2D::set_modification); + + ClassDB::bind_method(D_METHOD("set_modification_count"), &SkeletonModificationStack2D::set_modification_count); + ClassDB::bind_method(D_METHOD("get_modification_count"), &SkeletonModificationStack2D::get_modification_count); + + ClassDB::bind_method(D_METHOD("get_is_setup"), &SkeletonModificationStack2D::get_is_setup); + + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &SkeletonModificationStack2D::set_enabled); + ClassDB::bind_method(D_METHOD("get_enabled"), &SkeletonModificationStack2D::get_enabled); + + ClassDB::bind_method(D_METHOD("set_strength", "strength"), &SkeletonModificationStack2D::set_strength); + ClassDB::bind_method(D_METHOD("get_strength"), &SkeletonModificationStack2D::get_strength); + + ClassDB::bind_method(D_METHOD("get_skeleton"), &SkeletonModificationStack2D::get_skeleton); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "0, 1, 0.001"), "set_strength", "get_strength"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "modification_count", PROPERTY_HINT_RANGE, "0, 100, 1"), "set_modification_count", "get_modification_count"); +} + +SkeletonModificationStack2D::SkeletonModificationStack2D() { +} diff --git a/scene/resources/skeleton_modification_stack_2d.h b/scene/resources/skeleton_modification_stack_2d.h new file mode 100644 index 0000000000..58855701a1 --- /dev/null +++ b/scene/resources/skeleton_modification_stack_2d.h @@ -0,0 +1,99 @@ +/*************************************************************************/ +/* skeleton_modification_stack_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETONMODIFICATIONSTACK2D_H +#define SKELETONMODIFICATIONSTACK2D_H + +#include "scene/2d/skeleton_2d.h" +#include "scene/resources/skeleton_modification_2d.h" + +/////////////////////////////////////// +// SkeletonModificationStack2D +/////////////////////////////////////// + +class Skeleton2D; +class SkeletonModification2D; +class Bone2D; + +class SkeletonModificationStack2D : public Resource { + GDCLASS(SkeletonModificationStack2D, Resource); + friend class Skeleton2D; + friend class SkeletonModification2D; + +protected: + static void _bind_methods(); + void _get_property_list(List<PropertyInfo> *p_list) const; + bool _set(const StringName &p_path, const Variant &p_value); + bool _get(const StringName &p_path, Variant &r_ret) const; + +public: + Skeleton2D *skeleton = nullptr; + bool is_setup = false; + bool enabled = false; + float strength = 1.0; + + enum EXECUTION_MODE { + execution_mode_process, + execution_mode_physics_process + }; + + Vector<Ref<SkeletonModification2D>> modifications = Vector<Ref<SkeletonModification2D>>(); + + void setup(); + void execute(float p_delta, int p_execution_mode); + + bool editor_gizmo_dirty = false; + void draw_editor_gizmos(); + void set_editor_gizmos_dirty(bool p_dirty); + + void enable_all_modifications(bool p_enable); + Ref<SkeletonModification2D> get_modification(int p_mod_idx) const; + void add_modification(Ref<SkeletonModification2D> p_mod); + void delete_modification(int p_mod_idx); + void set_modification(int p_mod_idx, Ref<SkeletonModification2D> p_mod); + + void set_modification_count(int p_count); + int get_modification_count() const; + + void set_skeleton(Skeleton2D *p_skeleton); + Skeleton2D *get_skeleton() const; + + bool get_is_setup() const; + + void set_enabled(bool p_enabled); + bool get_enabled() const; + + void set_strength(float p_strength); + float get_strength() const; + + SkeletonModificationStack2D(); +}; + +#endif // SKELETONMODIFICATION2D_H diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index fee8fdbde2..710612ae05 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -38,14 +38,14 @@ void Skin::set_bind_count(int p_size) { emit_changed(); } -void Skin::add_bind(int p_bone, const Transform &p_pose) { +void Skin::add_bind(int p_bone, const Transform3D &p_pose) { uint32_t index = bind_count; set_bind_count(bind_count + 1); set_bind_bone(index, p_bone); set_bind_pose(index, p_pose); } -void Skin::add_named_bind(const String &p_name, const Transform &p_pose) { +void Skin::add_named_bind(const String &p_name, const Transform3D &p_pose) { uint32_t index = bind_count; set_bind_count(bind_count + 1); set_bind_name(index, p_name); @@ -68,7 +68,7 @@ void Skin::set_bind_bone(int p_index, int p_bone) { emit_changed(); } -void Skin::set_bind_pose(int p_index, const Transform &p_pose) { +void Skin::set_bind_pose(int p_index, const Transform3D &p_pose) { ERR_FAIL_INDEX(p_index, bind_count); binds_ptr[p_index].pose = p_pose; emit_changed(); @@ -134,7 +134,7 @@ void Skin::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < get_bind_count(); i++) { p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bind/" + itos(i) + "/name")); p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater", get_bind_name(i) != StringName() ? PROPERTY_USAGE_NOEDITOR : PROPERTY_USAGE_DEFAULT)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, "bind/" + itos(i) + "/pose")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, "bind/" + itos(i) + "/pose")); } } diff --git a/scene/resources/skin.h b/scene/resources/skin.h index f5d64f96aa..6857bf743a 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -39,7 +39,7 @@ class Skin : public Resource { struct Bind { int bone = -1; StringName name; - Transform pose; + Transform3D pose; }; Vector<Bind> binds; @@ -59,11 +59,11 @@ public: void set_bind_count(int p_size); inline int get_bind_count() const { return bind_count; } - void add_bind(int p_bone, const Transform &p_pose); - void add_named_bind(const String &p_name, const Transform &p_pose); + void add_bind(int p_bone, const Transform3D &p_pose); + void add_named_bind(const String &p_name, const Transform3D &p_pose); void set_bind_bone(int p_index, int p_bone); - void set_bind_pose(int p_index, const Transform &p_pose); + void set_bind_pose(int p_index, const Transform3D &p_pose); void set_bind_name(int p_index, const StringName &p_name); inline int get_bind_bone(int p_index) const { @@ -80,9 +80,9 @@ public: return binds_ptr[p_index].name; } - inline Transform get_bind_pose(int p_index) const { + inline Transform3D get_bind_pose(int p_index) const { #ifdef DEBUG_ENABLED - ERR_FAIL_INDEX_V(p_index, bind_count, Transform()); + ERR_FAIL_INDEX_V(p_index, bind_count, Transform3D()); #endif return binds_ptr[p_index].pose; } diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index f2143e683d..f728376310 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -857,7 +857,7 @@ void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_sur _create_list_from_arrays(arr[shape_idx], &vertex_array, &index_array, format); } -void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform) { +void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform3D &p_xform) { ERR_FAIL_NULL_MSG(p_existing, "First argument in SurfaceTool::append_from() must be a valid object of type Mesh"); if (vertex_array.size() == 0) { diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index f5f3a95b14..4674f0cc69 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -186,7 +186,7 @@ public: Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name); - void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); + void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform3D &p_xform); Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = 0); SurfaceTool(); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 786a96501a..12309f7488 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -553,6 +553,9 @@ void Theme::get_icon_list(StringName p_theme_type, List<StringName> *p_list) con } void Theme::add_icon_type(const StringName &p_theme_type) { + if (icon_map.has(p_theme_type)) { + return; + } icon_map[p_theme_type] = HashMap<StringName, Ref<Texture2D>>(); } @@ -641,6 +644,9 @@ void Theme::get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) } void Theme::add_stylebox_type(const StringName &p_theme_type) { + if (style_map.has(p_theme_type)) { + return; + } style_map[p_theme_type] = HashMap<StringName, Ref<StyleBox>>(); } @@ -730,6 +736,9 @@ void Theme::get_font_list(StringName p_theme_type, List<StringName> *p_list) con } void Theme::add_font_type(const StringName &p_theme_type) { + if (font_map.has(p_theme_type)) { + return; + } font_map[p_theme_type] = HashMap<StringName, Ref<Font>>(); } @@ -807,6 +816,9 @@ void Theme::get_font_size_list(StringName p_theme_type, List<StringName> *p_list } void Theme::add_font_size_type(const StringName &p_theme_type) { + if (font_size_map.has(p_theme_type)) { + return; + } font_size_map[p_theme_type] = HashMap<StringName, int>(); } @@ -882,6 +894,9 @@ void Theme::get_color_list(StringName p_theme_type, List<StringName> *p_list) co } void Theme::add_color_type(const StringName &p_theme_type) { + if (color_map.has(p_theme_type)) { + return; + } color_map[p_theme_type] = HashMap<StringName, Color>(); } @@ -956,6 +971,9 @@ void Theme::get_constant_list(StringName p_theme_type, List<StringName> *p_list) } void Theme::add_constant_type(const StringName &p_theme_type) { + if (constant_map.has(p_theme_type)) { + return; + } constant_map[p_theme_type] = HashMap<StringName, int>(); } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 2c2c8ea0e8..2220df06f6 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -3870,8 +3870,8 @@ void TileSetPluginAtlasRendering::tilemap_notification(TileMap *p_tile_map, int } break; case CanvasItem::NOTIFICATION_DRAW: { Ref<TileSet> tile_set = p_tile_map->get_tileset(); - if (tile_set.is_valid()) { - RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(p_tile_map->get_canvas_item(), tile_set->is_y_sorting()); + if (tile_set.is_valid() || p_tile_map->is_y_sort_enabled()) { + RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(p_tile_map->get_canvas_item(), tile_set->is_y_sorting() || p_tile_map->is_y_sort_enabled()); } } break; } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index f37b1a3e8e..5759948fe6 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -33,6 +33,7 @@ #include "core/templates/vmap.h" #include "servers/rendering/shader_types.h" #include "visual_shader_nodes.h" +#include "visual_shader_particle_nodes.h" #include "visual_shader_sdf_nodes.h" bool VisualShaderNode::is_simple_decl() const { @@ -60,6 +61,20 @@ Variant VisualShaderNode::get_input_port_default_value(int p_port) const { return Variant(); } +void VisualShaderNode::remove_input_port_default_value(int p_port) { + if (default_input_values.has(p_port)) { + default_input_values.erase(p_port); + emit_changed(); + } +} + +void VisualShaderNode::clear_default_input_values() { + if (!default_input_values.is_empty()) { + default_input_values.clear(); + emit_changed(); + } +} + bool VisualShaderNode::is_port_separator(int p_index) const { return false; } @@ -220,6 +235,9 @@ void VisualShaderNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value"), &VisualShaderNode::set_input_port_default_value); ClassDB::bind_method(D_METHOD("get_input_port_default_value", "port"), &VisualShaderNode::get_input_port_default_value); + ClassDB::bind_method(D_METHOD("remove_input_port_default_value", "port"), &VisualShaderNode::remove_input_port_default_value); + ClassDB::bind_method(D_METHOD("clear_default_input_values"), &VisualShaderNode::clear_default_input_values); + ClassDB::bind_method(D_METHOD("set_default_input_values", "values"), &VisualShaderNode::set_default_input_values); ClassDB::bind_method(D_METHOD("get_default_input_values"), &VisualShaderNode::get_default_input_values); @@ -373,6 +391,18 @@ void VisualShaderNodeCustom::set_default_input_values(const Array &p_values) { } } +void VisualShaderNodeCustom::remove_input_port_default_value(int p_port) { + if (!is_initialized) { + VisualShaderNode::remove_input_port_default_value(p_port); + } +} + +void VisualShaderNodeCustom::clear_default_input_values() { + if (!is_initialized) { + VisualShaderNode::clear_default_input_values(); + } +} + void VisualShaderNodeCustom::_set_input_port_default_value(int p_port, const Variant &p_value) { VisualShaderNode::set_input_port_default_value(p_port, p_value); } @@ -1050,9 +1080,11 @@ static const char *type_string[VisualShader::TYPE_MAX] = { "vertex", "fragment", "light", - "emit", + "start", "process", - "end", + "collide", + "start_custom", + "process_custom", "sky", }; @@ -1328,7 +1360,8 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui return OK; } - code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n"; + String node_name = "// " + vsnode->get_caption() + ":" + itos(node) + "\n"; + String node_code; Vector<String> input_vars; input_vars.resize(vsnode->get_input_port_count()); @@ -1399,21 +1432,21 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui if (defval.get_type() == Variant::FLOAT) { float val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n"; + node_code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n"; } else if (defval.get_type() == Variant::INT) { int val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\tint " + inputs[i] + " = " + itos(val) + ";\n"; + node_code += "\tint " + inputs[i] + " = " + itos(val) + ";\n"; } else if (defval.get_type() == Variant::BOOL) { bool val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n"; + node_code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n"; } else if (defval.get_type() == Variant::VECTOR3) { Vector3 val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z); - } else if (defval.get_type() == Variant::TRANSFORM) { - Transform val = defval; + node_code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z); + } else if (defval.get_type() == Variant::TRANSFORM3D) { + Transform3D val = defval; val.basis.transpose(); inputs[i] = "n_in" + itos(node) + "p" + itos(i); Array values; @@ -1426,7 +1459,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui values.push_back(val.origin.y); values.push_back(val.origin.z); bool err = false; - code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err); + node_code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err); } else { //will go empty, node is expected to know what it is doing at this point and handle it } @@ -1514,7 +1547,12 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } } - code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); + node_code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); + if (node_code != String()) { + code += node_name; + code += node_code; + code += "\n"; + } for (int i = 0; i < output_count; i++) { bool new_line_inserted = false; @@ -1564,7 +1602,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const { if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) { if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) { - if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") { + if (p_func_name == "start_custom" || p_func_name == "process_custom" || p_func_name == "collide") { return true; } } @@ -1645,11 +1683,12 @@ void VisualShader::_update_shader() const { global_code += "render_mode " + render_mode + ";\n\n"; } - static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end", "sky" }; + static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "start", "process", "collide", "start_custom", "process_custom", "sky" }; String global_expressions; Set<String> used_uniform_names; List<VisualShaderNodeUniform *> uniforms; + Map<int, List<int>> emitters; for (int i = 0, index = 0; i < TYPE_MAX; i++) { if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { @@ -1674,6 +1713,19 @@ void VisualShader::_update_shader() const { if (uniform.is_valid()) { uniforms.push_back(uniform.ptr()); } + Ref<VisualShaderNodeParticleEmit> emit_particle = Object::cast_to<VisualShaderNodeParticleEmit>(E->get().node.ptr()); + if (emit_particle.is_valid()) { + if (!emitters.has(i)) { + emitters.insert(i, List<int>()); + } + + for (Map<int, Node>::Element *M = graph[i].nodes.front(); M; M = M->next()) { + if (M->get().node == emit_particle.ptr()) { + emitters[i].push_back(M->key()); + break; + } + } + } } } @@ -1722,6 +1774,13 @@ void VisualShader::_update_shader() const { Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); ERR_FAIL_COND(err != OK); + if (emitters.has(i)) { + for (List<int>::Element *E = emitters[i].front(); E; E = E->next()) { + err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E->get(), processed, false, classes); + ERR_FAIL_COND(err != OK); + } + } + if (shader_mode == Shader::MODE_PARTICLES) { code_map.insert(i, func_code); } else { @@ -1730,19 +1789,130 @@ void VisualShader::_update_shader() const { } } + String global_compute_code; + if (shader_mode == Shader::MODE_PARTICLES) { - code += "\nvoid compute() {\n"; - code += "\tif (RESTART) {\n"; - code += code_map[TYPE_EMIT]; - code += "\t} else {\n"; - code += code_map[TYPE_PROCESS]; + bool has_start = !code_map[TYPE_START].is_empty(); + bool has_start_custom = !code_map[TYPE_START_CUSTOM].is_empty(); + bool has_process = !code_map[TYPE_PROCESS].is_empty(); + bool has_process_custom = !code_map[TYPE_PROCESS_CUSTOM].is_empty(); + bool has_collide = !code_map[TYPE_COLLIDE].is_empty(); + + code += "void start() {\n"; + if (has_start || has_start_custom) { + code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; + code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; + code += "\tfloat __radians;\n"; + code += "\tvec3 __vec3_buff1;\n"; + code += "\tvec3 __vec3_buff2;\n"; + code += "\tfloat __scalar_buff1;\n"; + code += "\tfloat __scalar_buff2;\n"; + code += "\tvec3 __ndiff = normalize(__diff);\n\n"; + } + if (has_start) { + code += "\t{\n"; + code += code_map[TYPE_START].replace("\n\t", "\n\t\t"); + code += "\t}\n"; + if (has_start_custom) { + code += "\t\n"; + } + } + if (has_start_custom) { + code += "\t{\n"; + code += code_map[TYPE_START_CUSTOM].replace("\n\t", "\n\t\t"); + code += "\t}\n"; + } + code += "}\n\n"; + code += "void process() {\n"; + if (has_process || has_process_custom || has_collide) { + code += "\tuint __seed = __hash(NUMBER + uint(1) + RANDOM_SEED);\n"; + code += "\tvec3 __vec3_buff1;\n"; + code += "\tvec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n"; + code += "\tvec3 __ndiff = normalize(__diff);\n\n"; + } + code += "\t{\n"; + String tab = "\t"; + if (has_collide) { + code += "\t\tif (COLLIDED) {\n\n"; + code += code_map[TYPE_COLLIDE].replace("\n\t", "\n\t\t\t"); + if (has_process) { + code += "\t\t} else {\n\n"; + tab += "\t"; + } + } + if (has_process) { + code += code_map[TYPE_PROCESS].replace("\n\t", "\n\t" + tab); + } + if (has_collide) { + code += "\t\t}\n"; + } code += "\t}\n"; - code += "}\n"; + + if (has_process_custom) { + code += "\t{\n\n"; + code += code_map[TYPE_PROCESS_CUSTOM].replace("\n\t", "\n\t\t"); + code += "\t}\n"; + } + + code += "}\n\n"; + + global_compute_code += "float __rand_from_seed(inout uint seed) {\n"; + global_compute_code += "\tint k;\n"; + global_compute_code += "\tint s = int(seed);\n"; + global_compute_code += "\tif (s == 0)\n"; + global_compute_code += "\ts = 305420679;\n"; + global_compute_code += "\tk = s / 127773;\n"; + global_compute_code += "\ts = 16807 * (s - k * 127773) - 2836 * k;\n"; + global_compute_code += "\tif (s < 0)\n"; + global_compute_code += "\t\ts += 2147483647;\n"; + global_compute_code += "\tseed = uint(s);\n"; + global_compute_code += "\treturn float(seed % uint(65536)) / 65535.0;\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "float __rand_from_seed_m1_p1(inout uint seed) {\n"; + global_compute_code += "\treturn __rand_from_seed(seed) * 2.0 - 1.0;\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "float __randf_range(inout uint seed, float from, float to) {\n"; + global_compute_code += "\treturn __rand_from_seed(seed) * (to - from) + from;\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "vec3 __randv_range(inout uint seed, vec3 from, vec3 to) {\n"; + global_compute_code += "\treturn vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "uint __hash(uint x) {\n"; + global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + global_compute_code += "\tx = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + global_compute_code += "\tx = (x >> uint(16)) ^ x;\n"; + global_compute_code += "\treturn x;\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "mat3 __build_rotation_mat3(vec3 axis, float angle) {\n"; + global_compute_code += "\taxis = normalize(axis);\n"; + global_compute_code += "\tfloat s = sin(angle);\n"; + global_compute_code += "\tfloat c = cos(angle);\n"; + global_compute_code += "\tfloat oc = 1.0 - c;\n"; + global_compute_code += "\treturn mat3(vec3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s), vec3(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s), vec3(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c));\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "mat4 __build_rotation_mat4(vec3 axis, float angle) {\n"; + global_compute_code += "\taxis = normalize(axis);\n"; + global_compute_code += "\tfloat s = sin(angle);\n"; + global_compute_code += "\tfloat c = cos(angle);\n"; + global_compute_code += "\tfloat oc = 1.0 - c;\n"; + global_compute_code += "\treturn mat4(vec4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0), vec4(oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0), vec4(oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0), vec4(0, 0, 0, 1));\n"; + global_compute_code += "}\n\n"; + + global_compute_code += "vec3 __get_random_unit_vec3(inout uint seed) {\n"; + global_compute_code += "\treturn normalize(vec3(__rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed), __rand_from_seed_m1_p1(seed)));\n"; + global_compute_code += "}\n\n"; } //set code secretly global_code += "\n\n"; String final_code = global_code; + final_code += global_compute_code; final_code += global_code_per_node; final_code += global_expressions; String tcode = code; @@ -1833,9 +2003,11 @@ void VisualShader::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_VERTEX); BIND_ENUM_CONSTANT(TYPE_FRAGMENT); BIND_ENUM_CONSTANT(TYPE_LIGHT); - BIND_ENUM_CONSTANT(TYPE_EMIT); + BIND_ENUM_CONSTANT(TYPE_START); BIND_ENUM_CONSTANT(TYPE_PROCESS); - BIND_ENUM_CONSTANT(TYPE_END); + BIND_ENUM_CONSTANT(TYPE_COLLIDE); + BIND_ENUM_CONSTANT(TYPE_START_CUSTOM); + BIND_ENUM_CONSTANT(TYPE_PROCESS_CUSTOM); BIND_ENUM_CONSTANT(TYPE_SKY); BIND_ENUM_CONSTANT(TYPE_MAX); @@ -1846,11 +2018,20 @@ void VisualShader::_bind_methods() { VisualShader::VisualShader() { dirty.set(); for (int i = 0; i < TYPE_MAX; i++) { - Ref<VisualShaderNodeOutput> output; - output.instance(); - output->shader_type = Type(i); - output->shader_mode = shader_mode; - graph[i].nodes[NODE_ID_OUTPUT].node = output; + if (i > (int)TYPE_LIGHT && i < (int)TYPE_SKY) { + Ref<VisualShaderNodeParticleOutput> output; + output.instance(); + output->shader_type = Type(i); + output->shader_mode = shader_mode; + graph[i].nodes[NODE_ID_OUTPUT].node = output; + } else { + Ref<VisualShaderNodeOutput> output; + output.instance(); + output->shader_type = Type(i); + output->shader_mode = shader_mode; + graph[i].nodes[NODE_ID_OUTPUT].node = output; + } + graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150); } } @@ -1979,27 +2160,45 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "specular_shininess_alpha", "SPECULAR_SHININESS.a" }, - // Particles, Emit - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Start + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, Start (Custom) + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Particles, Process + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, @@ -2009,20 +2208,39 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - // Particles, End - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Process (Custom) + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, Collide + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "attractor_force", "ATTRACTOR_FORCE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "collision_depth", "COLLISION_DEPTH" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "collision_normal", "COLLISION_NORMAL" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_BOOLEAN, "restart", "RESTART" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Sky, Sky { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" }, @@ -2098,11 +2316,13 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - // Particles, Vertex - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0, 0.0, 1.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles + { Shader::MODE_PARTICLES, VisualShader::TYPE_START, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_COLLIDE, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_START_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS_CUSTOM, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, nullptr, nullptr }, }; @@ -2595,30 +2815,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" }, - // Particles, Emit - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, - // Particles, Process - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, - // Particles, End - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + // Sky, Sky { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" }, { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" }, diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index aa7768751e..53b165fe0f 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -51,9 +51,11 @@ public: TYPE_VERTEX, TYPE_FRAGMENT, TYPE_LIGHT, - TYPE_EMIT, + TYPE_START, TYPE_PROCESS, - TYPE_END, + TYPE_COLLIDE, + TYPE_START_CUSTOM, + TYPE_PROCESS_CUSTOM, TYPE_SKY, TYPE_MAX }; @@ -230,6 +232,8 @@ public: Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied) Array get_default_input_values() const; virtual void set_default_input_values(const Array &p_values); + virtual void remove_input_port_default_value(int p_port); + virtual void clear_default_input_values(); virtual int get_output_port_count() const = 0; virtual PortType get_output_port_type(int p_port) const = 0; @@ -305,6 +309,8 @@ protected: virtual void set_input_port_default_value(int p_port, const Variant &p_value) override; virtual void set_default_input_values(const Array &p_values) override; + virtual void remove_input_port_default_value(int p_port) override; + virtual void clear_default_input_values() override; protected: void _set_input_port_default_value(int p_port, const Variant &p_value); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index e7cc78cb3a..d3b094de31 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -341,10 +341,10 @@ void VisualShaderNodeVec3Constant::_bind_methods() { VisualShaderNodeVec3Constant::VisualShaderNodeVec3Constant() { } -////////////// Transform +////////////// Transform3D String VisualShaderNodeTransformConstant::get_caption() const { - return "Transform"; + return "Transform3D"; } int VisualShaderNodeTransformConstant::get_input_port_count() const { @@ -372,7 +372,7 @@ String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const } String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - Transform t = constant; + Transform3D t = constant; t.basis.transpose(); String code = "\t" + p_output_vars[0] + " = mat4("; @@ -383,12 +383,12 @@ String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, Vis return code; } -void VisualShaderNodeTransformConstant::set_constant(Transform p_value) { +void VisualShaderNodeTransformConstant::set_constant(Transform3D p_value) { constant = p_value; emit_changed(); } -Transform VisualShaderNodeTransformConstant::get_constant() const { +Transform3D VisualShaderNodeTransformConstant::get_constant() const { return constant; } @@ -402,7 +402,7 @@ void VisualShaderNodeTransformConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeTransformConstant::set_constant); ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeTransformConstant::get_constant); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "constant"), "set_constant", "get_constant"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "constant"), "set_constant", "get_constant"); } VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() { @@ -860,7 +860,7 @@ String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualSh } String id = make_unique_id(p_type, p_id, "curve"); String code; - code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ", 0.0)).r;\n"; + code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).r;\n"; return code; } @@ -1901,8 +1901,8 @@ void VisualShaderNodeTransformMult::_bind_methods() { } VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() { - set_input_port_default_value(0, Transform()); - set_input_port_default_value(1, Transform()); + set_input_port_default_value(0, Transform3D()); + set_input_port_default_value(1, Transform3D()); } ////////////// TransformVec Mult @@ -1975,7 +1975,7 @@ void VisualShaderNodeTransformVecMult::_bind_methods() { } VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() { - set_input_port_default_value(0, Transform()); + set_input_port_default_value(0, Transform3D()); set_input_port_default_value(1, Vector3()); } @@ -2496,7 +2496,144 @@ void VisualShaderNodeTransformFunc::_bind_methods() { } VisualShaderNodeTransformFunc::VisualShaderNodeTransformFunc() { - set_input_port_default_value(0, Transform()); + set_input_port_default_value(0, Transform3D()); +} + +////////////// UV Func + +String VisualShaderNodeUVFunc::get_caption() const { + return "UVFunc"; +} + +int VisualShaderNodeUVFunc::get_input_port_count() const { + return 3; +} + +VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + [[fallthrough]]; // uv + case 1: + return PORT_TYPE_VECTOR; // scale + case 2: + return PORT_TYPE_VECTOR; // offset & pivot + default: + break; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeUVFunc::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "uv"; + case 1: + return "scale"; + case 2: + switch (func) { + case FUNC_PANNING: + return "offset"; + case FUNC_SCALING: + return "pivot"; + case FUNC_MAX: + break; + default: + break; + } + break; + default: + break; + } + return ""; +} + +String VisualShaderNodeUVFunc::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "UV"; + } + return ""; +} + +int VisualShaderNodeUVFunc::get_output_port_count() const { + return 1; +} + +VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeUVFunc::get_output_port_name(int p_port) const { + return "uv"; +} + +bool VisualShaderNodeUVFunc::is_show_prop_names() const { + return true; +} + +String VisualShaderNodeUVFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + String uv; + if (p_input_vars[0].is_empty()) { + uv = "vec3(UV.xy, 0.0)"; + } else { + uv = vformat("%s", p_input_vars[0]); + } + String scale = vformat("%s", p_input_vars[1]); + String offset_pivot = vformat("%s", p_input_vars[2]); + + switch (func) { + case FUNC_PANNING: { + code += vformat("\t%s = fma(%s, %s, %s);\n", p_output_vars[0], offset_pivot, scale, uv); + } break; + case FUNC_SCALING: { + code += vformat("\t%s = fma((%s - %s), %s, %s);\n", p_output_vars[0], uv, offset_pivot, scale, offset_pivot); + } break; + case FUNC_MAX: + break; + } + return code; +} + +void VisualShaderNodeUVFunc::set_function(VisualShaderNodeUVFunc::Function p_func) { + ERR_FAIL_INDEX(int(p_func), FUNC_MAX); + if (func == p_func) { + return; + } + func = p_func; + + if (p_func == FUNC_PANNING) { + set_input_port_default_value(2, Vector3()); // offset + } else { // FUNC_SCALING + set_input_port_default_value(2, Vector3(0.5, 0.5, 0.0)); // pivot + } + emit_changed(); +} + +VisualShaderNodeUVFunc::Function VisualShaderNodeUVFunc::get_function() const { + return func; +} + +Vector<StringName> VisualShaderNodeUVFunc::get_editable_properties() const { + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeUVFunc::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeUVFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeUVFunc::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Panning,Scaling"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_PANNING); + BIND_ENUM_CONSTANT(FUNC_SCALING); + BIND_ENUM_CONSTANT(FUNC_MAX); +} + +VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() { + set_input_port_default_value(1, Vector3(1.0, 1.0, 0.0)); // scale + set_input_port_default_value(2, Vector3()); // offset } ////////////// Dot Product @@ -2611,7 +2748,7 @@ String VisualShaderNodeDeterminant::generate_code(Shader::Mode p_mode, VisualSha } VisualShaderNodeDeterminant::VisualShaderNodeDeterminant() { - set_input_port_default_value(0, Transform()); + set_input_port_default_value(0, Transform3D()); } ////////////// Scalar Derivative Function @@ -3622,7 +3759,7 @@ String VisualShaderNodeTransformDecompose::generate_code(Shader::Mode p_mode, Vi } VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() { - set_input_port_default_value(0, Transform()); + set_input_port_default_value(0, Transform3D()); } ////////////// Float Uniform @@ -4308,12 +4445,12 @@ bool VisualShaderNodeTransformUniform::is_default_value_enabled() const { return default_value_enabled; } -void VisualShaderNodeTransformUniform::set_default_value(const Transform &p_value) { +void VisualShaderNodeTransformUniform::set_default_value(const Transform3D &p_value) { default_value = p_value; emit_changed(); } -Transform VisualShaderNodeTransformUniform::get_default_value() const { +Transform3D VisualShaderNodeTransformUniform::get_default_value() const { return default_value; } @@ -4342,7 +4479,7 @@ void VisualShaderNodeTransformUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "default_value"), "set_default_value", "get_default_value"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "default_value"), "set_default_value", "get_default_value"); } bool VisualShaderNodeTransformUniform::is_show_prop_names() const { @@ -5025,8 +5162,8 @@ void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) { set_input_port_default_value(2, false); break; case OP_TYPE_TRANSFORM: - set_input_port_default_value(1, Transform()); - set_input_port_default_value(2, Transform()); + set_input_port_default_value(1, Transform3D()); + set_input_port_default_value(2, Transform3D()); break; default: break; @@ -5405,8 +5542,8 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) { simple_decl = true; break; case CTYPE_TRANSFORM: - set_input_port_default_value(0, Transform()); - set_input_port_default_value(1, Transform()); + set_input_port_default_value(0, Transform3D()); + set_input_port_default_value(1, Transform3D()); simple_decl = true; break; } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 1c70459e3b..5b44e9f776 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -209,7 +209,7 @@ public: class VisualShaderNodeTransformConstant : public VisualShaderNodeConstant { GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNodeConstant); - Transform constant; + Transform3D constant; protected: static void _bind_methods(); @@ -227,8 +227,8 @@ public: virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; - void set_constant(Transform p_value); - Transform get_constant() const; + void set_constant(Transform3D p_value); + Transform3D get_constant() const; virtual Vector<StringName> get_editable_properties() const override; @@ -1019,6 +1019,51 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeTransformFunc::Function) /////////////////////////////////////// +/// UV FUNC +/////////////////////////////////////// + +class VisualShaderNodeUVFunc : public VisualShaderNode { + GDCLASS(VisualShaderNodeUVFunc, VisualShaderNode); + +public: + enum Function { + FUNC_PANNING, + FUNC_SCALING, + FUNC_MAX, + }; + +protected: + Function func = FUNC_PANNING; + + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + virtual String get_input_port_default_hint(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual bool is_show_prop_names() const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + void set_function(Function p_op); + Function get_function() const; + + virtual Vector<StringName> get_editable_properties() const override; + + VisualShaderNodeUVFunc(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeUVFunc::Function) + +/////////////////////////////////////// /// DOT /////////////////////////////////////// @@ -1788,7 +1833,7 @@ class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform { private: bool default_value_enabled = false; - Transform default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0); + Transform3D default_value = Transform3D(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0); protected: static void _bind_methods(); @@ -1813,8 +1858,8 @@ public: void set_default_value_enabled(bool p_enabled); bool is_default_value_enabled() const; - void set_default_value(const Transform &p_value); - Transform get_default_value() const; + void set_default_value(const Transform3D &p_value); + Transform3D get_default_value() const; bool is_qualifier_supported(Qualifier p_qual) const override; bool is_convertible_to_constant() const override; diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp new file mode 100644 index 0000000000..29d583a82a --- /dev/null +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -0,0 +1,1025 @@ +/*************************************************************************/ +/* visual_shader_particle_nodes.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "visual_shader_particle_nodes.h" + +// VisualShaderNodeParticleEmitter + +int VisualShaderNodeParticleEmitter::get_output_port_count() const { + return 1; +} + +VisualShaderNodeParticleEmitter::PortType VisualShaderNodeParticleEmitter::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeParticleEmitter::get_output_port_name(int p_port) const { + if (p_port == 0) { + return "position"; + } + return String(); +} + +VisualShaderNodeParticleEmitter::VisualShaderNodeParticleEmitter() { +} + +// VisualShaderNodeParticleSphereEmitter + +String VisualShaderNodeParticleSphereEmitter::get_caption() const { + return "SphereEmitter"; +} + +int VisualShaderNodeParticleSphereEmitter::get_input_port_count() const { + return 2; +} + +VisualShaderNodeParticleSphereEmitter::PortType VisualShaderNodeParticleSphereEmitter::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleSphereEmitter::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "radius"; + } else if (p_port == 1) { + return "inner_radius"; + } + return String(); +} + +String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code; + code += "vec3 __get_random_point_in_sphere(inout uint seed, float radius, float inner_radius) {\n"; + code += "\treturn __get_random_unit_vec3(seed) * __randf_range(seed, inner_radius, radius);\n"; + code += "}\n\n"; + return code; +} + +String VisualShaderNodeParticleSphereEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + code += "\t" + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n"; + return code; +} + +VisualShaderNodeParticleSphereEmitter::VisualShaderNodeParticleSphereEmitter() { + set_input_port_default_value(0, 10.0); + set_input_port_default_value(1, 0.0); +} + +// VisualShaderNodeParticleBoxEmitter + +String VisualShaderNodeParticleBoxEmitter::get_caption() const { + return "BoxEmitter"; +} + +int VisualShaderNodeParticleBoxEmitter::get_input_port_count() const { + return 1; +} + +VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleBoxEmitter::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "extents"; + } + return String(); +} + +String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code; + code += "vec3 __get_random_point_in_box(inout uint seed, vec3 extents) {\n"; + code += "\tvec3 half_extents = extents / 2.0;\n"; + code += "\treturn vec3(__randf_range(seed, -half_extents.x, half_extents.x), __randf_range(seed, -half_extents.y, half_extents.y), __randf_range(seed, -half_extents.z, half_extents.z));\n"; + code += "}\n\n"; + return code; +} + +String VisualShaderNodeParticleBoxEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + code += "\t" + p_output_vars[0] + " = __get_random_point_in_box(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n"; + return code; +} + +VisualShaderNodeParticleBoxEmitter::VisualShaderNodeParticleBoxEmitter() { + set_input_port_default_value(0, Vector3(1.0, 1.0, 1.0)); +} + +// VisualShaderNodeParticleRingEmitter + +String VisualShaderNodeParticleRingEmitter::get_caption() const { + return "RingEmitter"; +} + +int VisualShaderNodeParticleRingEmitter::get_input_port_count() const { + return 3; +} + +VisualShaderNodeParticleRingEmitter::PortType VisualShaderNodeParticleRingEmitter::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleRingEmitter::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "radius"; + } else if (p_port == 1) { + return "inner_radius"; + } else if (p_port == 2) { + return "height"; + } + return String(); +} + +String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code; + code += "vec3 __get_random_point_on_ring(inout uint seed, float radius, float inner_radius, float height) {\n"; + code += "\tfloat angle = __rand_from_seed(seed) * PI * 2.0;\n"; + code += "\tvec2 ring = vec2(sin(angle), cos(angle)) * __randf_range(seed, inner_radius, radius);\n"; + code += "\treturn vec3(ring.x, __randf_range(seed, min(0.0, height), max(0.0, height)), ring.y);\n"; + code += "}\n\n"; + return code; +} + +String VisualShaderNodeParticleRingEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + code = "\t" + p_output_vars[0] + " = __get_random_point_on_ring(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n"; + return code; +} + +VisualShaderNodeParticleRingEmitter::VisualShaderNodeParticleRingEmitter() { + set_input_port_default_value(0, 10.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 0.0); +} + +// VisualShaderNodeParticleMultiplyByAxisAngle + +void VisualShaderNodeParticleMultiplyByAxisAngle::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_degrees_mode", "enabled"), &VisualShaderNodeParticleMultiplyByAxisAngle::set_degrees_mode); + ClassDB::bind_method(D_METHOD("is_degrees_mode"), &VisualShaderNodeParticleMultiplyByAxisAngle::is_degrees_mode); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "degrees_mode"), "set_degrees_mode", "is_degrees_mode"); +} + +String VisualShaderNodeParticleMultiplyByAxisAngle::get_caption() const { + return "MultiplyByAxisAngle"; +} + +int VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_count() const { + return 3; +} + +VisualShaderNodeParticleMultiplyByAxisAngle::PortType VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_type(int p_port) const { + if (p_port == 0 || p_port == 1) { // position, rotation_axis + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; // angle (degrees/radians) +} + +String VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "position"; + } + if (p_port == 1) { + return "axis"; + } + if (p_port == 2) { + if (degrees_mode) { + return "angle (degrees)"; + } else { + return "angle (radians)"; + } + } + return String(); +} + +bool VisualShaderNodeParticleMultiplyByAxisAngle::is_show_prop_names() const { + return true; +} + +int VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_count() const { + return 1; +} + +VisualShaderNodeParticleMultiplyByAxisAngle::PortType VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_name(int p_port) const { + return "position"; +} + +String VisualShaderNodeParticleMultiplyByAxisAngle::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + if (degrees_mode) { + code += "\t" + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", radians(" + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ")) * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n"; + } else { + code += "\t" + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ") * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n"; + } + return code; +} + +void VisualShaderNodeParticleMultiplyByAxisAngle::set_degrees_mode(bool p_enabled) { + degrees_mode = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeParticleMultiplyByAxisAngle::is_degrees_mode() const { + return degrees_mode; +} + +Vector<StringName> VisualShaderNodeParticleMultiplyByAxisAngle::get_editable_properties() const { + Vector<StringName> props; + props.push_back("degrees_mode"); + props.push_back("axis_amount"); + return props; +} + +VisualShaderNodeParticleMultiplyByAxisAngle::VisualShaderNodeParticleMultiplyByAxisAngle() { + set_input_port_default_value(1, Vector3(1, 0, 0)); + set_input_port_default_value(2, 0.0); +} + +// VisualShaderNodeParticleConeVelocity + +String VisualShaderNodeParticleConeVelocity::get_caption() const { + return "ConeVelocity"; +} + +int VisualShaderNodeParticleConeVelocity::get_input_port_count() const { + return 2; +} + +VisualShaderNodeParticleConeVelocity::PortType VisualShaderNodeParticleConeVelocity::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_SCALAR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleConeVelocity::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "direction"; + } else if (p_port == 1) { + return "spread(degrees)"; + } + return String(); +} + +int VisualShaderNodeParticleConeVelocity::get_output_port_count() const { + return 1; +} + +VisualShaderNodeParticleConeVelocity::PortType VisualShaderNodeParticleConeVelocity::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeParticleConeVelocity::get_output_port_name(int p_port) const { + if (p_port == 0) { + return "velocity"; + } + return String(); +} + +String VisualShaderNodeParticleConeVelocity::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + code += "\t__radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n"; + code += "\t__scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n"; + code += "\t__scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n"; + code += "\t__vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n"; + code += "\t__scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n"; + code += "\t__scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n"; + code += "\t__vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n"; + code += "\t__vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n"; + code += "\t__vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n"; + code += "\t" + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n"; + return code; +} + +VisualShaderNodeParticleConeVelocity::VisualShaderNodeParticleConeVelocity() { + set_input_port_default_value(0, Vector3(1, 0, 0)); + set_input_port_default_value(1, 45.0); +} + +// VisualShaderNodeParticleRandomness + +void VisualShaderNodeParticleRandomness::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeParticleRandomness::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeParticleRandomness::get_op_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); +} + +Vector<StringName> VisualShaderNodeParticleRandomness::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; +} + +String VisualShaderNodeParticleRandomness::get_caption() const { + return "ParticleRandomness"; +} + +int VisualShaderNodeParticleRandomness::get_output_port_count() const { + return 1; +} + +VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_output_port_type(int p_port) const { + if (op_type == OP_TYPE_VECTOR) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleRandomness::get_output_port_name(int p_port) const { + return "random"; +} + +int VisualShaderNodeParticleRandomness::get_input_port_count() const { + return 2; +} + +VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_input_port_type(int p_port) const { + if (op_type == OP_TYPE_VECTOR) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleRandomness::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "min"; + } else if (p_port == 1) { + return "max"; + } + return String(); +} + +String VisualShaderNodeParticleRandomness::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + if (op_type == OP_TYPE_SCALAR) { + code += vformat("\t%s = __randf_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + } else if (op_type == OP_TYPE_VECTOR) { + code += vformat("\t%s = __randv_range(__seed, %s, %s);\n", p_output_vars[0], p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]); + } + return code; +} + +void VisualShaderNodeParticleRandomness::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (p_op_type != op_type) { + if (p_op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 1.0); + } else { + set_input_port_default_value(0, Vector3(-1.0, -1.0, -1.0)); + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + } + } + op_type = p_op_type; + emit_changed(); +} + +VisualShaderNodeParticleRandomness::OpType VisualShaderNodeParticleRandomness::get_op_type() const { + return op_type; +} + +VisualShaderNodeParticleRandomness::VisualShaderNodeParticleRandomness() { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 1.0); +} + +// VisualShaderNodeParticleAccelerator + +void VisualShaderNodeParticleAccelerator::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VisualShaderNodeParticleAccelerator::set_mode); + ClassDB::bind_method(D_METHOD("get_mode"), &VisualShaderNodeParticleAccelerator::get_mode); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Linear,Radial,Tangential"), "set_mode", "get_mode"); + + BIND_ENUM_CONSTANT(MODE_LINEAR); + BIND_ENUM_CONSTANT(MODE_RADIAL) + BIND_ENUM_CONSTANT(MODE_TANGENTIAL); + BIND_ENUM_CONSTANT(MODE_MAX); +} + +Vector<StringName> VisualShaderNodeParticleAccelerator::get_editable_properties() const { + Vector<StringName> props; + props.push_back("mode"); + return props; +} + +String VisualShaderNodeParticleAccelerator::get_caption() const { + return "ParticleAccelerator"; +} + +int VisualShaderNodeParticleAccelerator::get_output_port_count() const { + return 1; +} + +VisualShaderNodeParticleAccelerator::PortType VisualShaderNodeParticleAccelerator::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeParticleAccelerator::get_output_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeParticleAccelerator::get_input_port_count() const { + return 3; +} + +VisualShaderNodeParticleAccelerator::PortType VisualShaderNodeParticleAccelerator::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_SCALAR; + } else if (p_port == 2) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleAccelerator::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "amount"; + } else if (p_port == 1) { + return "randomness"; + } else if (p_port == 2) { + return "axis"; + } + return String(); +} + +String VisualShaderNodeParticleAccelerator::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + switch (mode) { + case MODE_LINEAR: + code += "\t" + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n"; + break; + case MODE_RADIAL: + code += "\t" + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n"; + break; + case MODE_TANGENTIAL: + code += "\t__vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n"; + code += "\t" + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n"; + break; + case MODE_MAX: + break; + default: + break; + } + + return code; +} + +void VisualShaderNodeParticleAccelerator::set_mode(Mode p_mode) { + mode = p_mode; + emit_changed(); +} + +VisualShaderNodeParticleAccelerator::Mode VisualShaderNodeParticleAccelerator::get_mode() const { + return mode; +} + +VisualShaderNodeParticleAccelerator::VisualShaderNodeParticleAccelerator() { + set_input_port_default_value(0, Vector3(1, 1, 1)); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, Vector3(0, -9.8, 0)); +} + +// VisualShaderNodeParticleOutput + +String VisualShaderNodeParticleOutput::get_caption() const { + if (shader_type == VisualShader::TYPE_START) { + return "StartOutput"; + } else if (shader_type == VisualShader::TYPE_PROCESS) { + return "ProcessOutput"; + } else if (shader_type == VisualShader::TYPE_COLLIDE) { + return "CollideOutput"; + } else if (shader_type == VisualShader::TYPE_START_CUSTOM) { + return "CustomStartOutput"; + } else if (shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + return "CustomProcessOutput"; + } + return String(); +} + +int VisualShaderNodeParticleOutput::get_input_port_count() const { + if (shader_type == VisualShader::TYPE_START) { + return 8; + } else if (shader_type == VisualShader::TYPE_COLLIDE) { + return 5; + } else if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + return 6; + } else { // TYPE_PROCESS + return 7; + } + return 0; +} + +VisualShaderNodeParticleOutput::PortType VisualShaderNodeParticleOutput::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + return PORT_TYPE_VECTOR; // custom.rgb + } + return PORT_TYPE_BOOLEAN; // active + case 1: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + break; // custom.a (scalar) + } + return PORT_TYPE_VECTOR; // velocity + case 2: + return PORT_TYPE_VECTOR; // color & velocity + case 3: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + return PORT_TYPE_VECTOR; // color + } + break; // alpha (scalar) + case 4: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + break; // alpha + } + if (shader_type == VisualShader::TYPE_PROCESS) { + break; // scale + } + if (shader_type == VisualShader::TYPE_COLLIDE) { + return PORT_TYPE_TRANSFORM; // transform + } + return PORT_TYPE_VECTOR; // position + case 5: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + return PORT_TYPE_TRANSFORM; // transform + } + if (shader_type == VisualShader::TYPE_PROCESS) { + return PORT_TYPE_VECTOR; // rotation_axis + } + break; // scale (scalar) + case 6: + if (shader_type == VisualShader::TYPE_START) { + return PORT_TYPE_VECTOR; // rotation_axis + } + break; + case 7: + break; // angle (scalar) + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleOutput::get_input_port_name(int p_port) const { + String port_name; + switch (p_port) { + case 0: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "custom"; + break; + } + port_name = "active"; + break; + case 1: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "custom_alpha"; + break; + } + port_name = "velocity"; + break; + case 2: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "velocity"; + break; + } + port_name = "color"; + break; + case 3: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "color"; + break; + } + port_name = "alpha"; + break; + case 4: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "alpha"; + break; + } + if (shader_type == VisualShader::TYPE_PROCESS) { + port_name = "scale"; + break; + } + if (shader_type == VisualShader::TYPE_COLLIDE) { + port_name = "transform"; + break; + } + port_name = "position"; + break; + case 5: + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + port_name = "transform"; + break; + } + if (shader_type == VisualShader::TYPE_PROCESS) { + port_name = "rotation_axis"; + break; + } + port_name = "scale"; + break; + case 6: + if (shader_type == VisualShader::TYPE_PROCESS) { + port_name = "angle_in_radians"; + break; + } + port_name = "rotation_axis"; + break; + case 7: + port_name = "angle_in_radians"; + break; + default: + break; + } + if (!port_name.is_empty()) { + return port_name.capitalize(); + } + return String(); +} + +bool VisualShaderNodeParticleOutput::is_port_separator(int p_index) const { + if (shader_type == VisualShader::TYPE_START || shader_type == VisualShader::TYPE_PROCESS) { + String name = get_input_port_name(p_index); + return bool(name == "Scale"); + } + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + String name = get_input_port_name(p_index); + return bool(name == "Velocity"); + } + return false; +} + +String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + String tab = "\t"; + + if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) { + if (!p_input_vars[0].is_empty()) { // custom.rgb + code += tab + "CUSTOM.rgb = " + p_input_vars[0] + ";\n"; + } + if (!p_input_vars[1].is_empty()) { // custom.a + code += tab + "CUSTOM.a = " + p_input_vars[1] + ";\n"; + } + if (!p_input_vars[2].is_empty()) { // velocity + code += tab + "VELOCITY = " + p_input_vars[2] + ";\n"; + } + if (!p_input_vars[3].is_empty()) { // color.rgb + code += tab + "COLOR.rgb = " + p_input_vars[3] + ";\n"; + } + if (!p_input_vars[4].is_empty()) { // color.a + code += tab + "COLOR.a = " + p_input_vars[4] + ";\n"; + } + if (!p_input_vars[5].is_empty()) { // transform + code += tab + "TRANSFORM = " + p_input_vars[5] + ";\n"; + } + } else { + if (!p_input_vars[0].is_empty()) { // active (begin) + code += tab + "ACTIVE = " + p_input_vars[0] + ";\n"; + code += tab + "if(ACTIVE) {\n"; + tab += "\t"; + } + if (!p_input_vars[1].is_empty()) { // velocity + code += tab + "VELOCITY = " + p_input_vars[1] + ";\n"; + } + if (!p_input_vars[2].is_empty()) { // color + code += tab + "COLOR.rgb = " + p_input_vars[2] + ";\n"; + } + if (!p_input_vars[3].is_empty()) { // alpha + code += tab + "COLOR.a = " + p_input_vars[3] + ";\n"; + } + + // position + if (shader_type == VisualShader::TYPE_START) { + code += tab + "if (RESTART_POSITION) {\n"; + if (!p_input_vars[4].is_empty()) { + code += tab + "\tTRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(" + p_input_vars[4] + ", 1.0));\n"; + } else { + code += tab + "\tTRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + } + code += tab + "\tif (RESTART_VELOCITY) {\n"; + code += tab + "\t\tVELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; + code += tab + "\t}\n"; + code += tab + "\tTRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; + code += tab + "}\n"; + } else if (shader_type == VisualShader::TYPE_COLLIDE) { // position + if (!p_input_vars[4].is_empty()) { + code += tab + "TRANSFORM = " + p_input_vars[4] + ";\n"; + } + } + + if (shader_type == VisualShader::TYPE_START || shader_type == VisualShader::TYPE_PROCESS) { + int scale = 5; + int rotation_axis = 6; + int rotation = 7; + if (shader_type == VisualShader::TYPE_PROCESS) { + scale = 4; + rotation_axis = 5; + rotation = 6; + } + String op; + if (shader_type == VisualShader::TYPE_START) { + op = "*="; + } else { + op = "="; + } + + if (!p_input_vars[rotation].is_empty()) { // rotation_axis & angle_in_radians + String axis; + if (p_input_vars[rotation_axis].is_empty()) { + axis = "vec3(0, 1, 0)"; + } else { + axis = p_input_vars[rotation_axis]; + } + code += tab + "TRANSFORM " + op + " __build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ");\n"; + } + if (!p_input_vars[scale].is_empty()) { // scale + code += tab + "TRANSFORM " + op + " mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0, 0, 0, 1));\n"; + } + } + if (!p_input_vars[0].is_empty()) { // active (end) + code += "\t}\n"; + } + } + return code; +} + +VisualShaderNodeParticleOutput::VisualShaderNodeParticleOutput() { +} + +// EmitParticle + +Vector<StringName> VisualShaderNodeParticleEmit::get_editable_properties() const { + Vector<StringName> props; + props.push_back("flags"); + return props; +} + +void VisualShaderNodeParticleEmit::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_flags", "flags"), &VisualShaderNodeParticleEmit::set_flags); + ClassDB::bind_method(D_METHOD("get_flags"), &VisualShaderNodeParticleEmit::get_flags); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Position,RotScale,Velocity,Color,Custom"), "set_flags", "get_flags"); + + BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION); + BIND_ENUM_CONSTANT(EMIT_FLAG_ROT_SCALE); + BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY); + BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR); + BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM); +} + +String VisualShaderNodeParticleEmit::get_caption() const { + return "EmitParticle"; +} + +int VisualShaderNodeParticleEmit::get_input_port_count() const { + return 7; +} + +VisualShaderNodeParticleEmit::PortType VisualShaderNodeParticleEmit::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_BOOLEAN; + case 1: + return PORT_TYPE_TRANSFORM; + case 2: + return PORT_TYPE_VECTOR; + case 3: + return PORT_TYPE_VECTOR; + case 4: + return PORT_TYPE_SCALAR; + case 5: + return PORT_TYPE_VECTOR; + case 6: + return PORT_TYPE_SCALAR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleEmit::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "condition"; + case 1: + return "transform"; + case 2: + return "velocity"; + case 3: + return "color"; + case 4: + return "alpha"; + case 5: + return "custom"; + case 6: + return "custom_alpha"; + } + return String(); +} + +int VisualShaderNodeParticleEmit::get_output_port_count() const { + return 0; +} + +VisualShaderNodeParticleEmit::PortType VisualShaderNodeParticleEmit::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeParticleEmit::get_output_port_name(int p_port) const { + return String(); +} + +void VisualShaderNodeParticleEmit::add_flag(EmitFlags p_flag) { + flags |= p_flag; + emit_changed(); +} + +bool VisualShaderNodeParticleEmit::has_flag(EmitFlags p_flag) const { + return flags & p_flag; +} + +void VisualShaderNodeParticleEmit::set_flags(EmitFlags p_flags) { + flags = (int)p_flags; + emit_changed(); +} + +VisualShaderNodeParticleEmit::EmitFlags VisualShaderNodeParticleEmit::get_flags() const { + return EmitFlags(flags); +} + +bool VisualShaderNodeParticleEmit::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeParticleEmit::is_generate_input_var(int p_port) const { + if (p_port == 0) { + if (!is_input_port_connected(0)) { + return false; + } + } + return true; +} + +String VisualShaderNodeParticleEmit::get_input_port_default_hint(int p_port) const { + switch (p_port) { + case 1: + return "default"; + case 2: + return "default"; + case 3: + return "default"; + case 4: + return "default"; + case 5: + return "default"; + case 6: + return "default"; + } + return String(); +} + +String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + String tab; + bool default_condition = false; + + if (!is_input_port_connected(0)) { + default_condition = true; + if (get_input_port_default_value(0)) { + tab = "\t"; + } else { + return code; + } + } else { + tab = "\t\t"; + } + + String transform; + if (p_input_vars[1].is_empty()) { + transform = "TRANSFORM"; + } else { + transform = p_input_vars[1]; + } + + String velocity; + if (p_input_vars[2].is_empty()) { + velocity = "VELOCITY"; + } else { + velocity = p_input_vars[2]; + } + + String color; + if (p_input_vars[3].is_empty()) { + color = "COLOR.rgb"; + } else { + color = p_input_vars[3]; + } + + String alpha; + if (p_input_vars[4].is_empty()) { + alpha = "COLOR.a"; + } else { + alpha = p_input_vars[4]; + } + + String custom; + if (p_input_vars[5].is_empty()) { + custom = "CUSTOM.rgb"; + } else { + custom = p_input_vars[5]; + } + + String custom_alpha; + if (p_input_vars[6].is_empty()) { + custom_alpha = "CUSTOM.a"; + } else { + custom_alpha = p_input_vars[6]; + } + + List<String> flags_arr; + + if (has_flag(EmitFlags::EMIT_FLAG_POSITION)) { + flags_arr.push_back("FLAG_EMIT_POSITION"); + } + if (has_flag(EmitFlags::EMIT_FLAG_ROT_SCALE)) { + flags_arr.push_back("FLAG_EMIT_ROT_SCALE"); + } + if (has_flag(EmitFlags::EMIT_FLAG_VELOCITY)) { + flags_arr.push_back("FLAG_EMIT_VELOCITY"); + } + if (has_flag(EmitFlags::EMIT_FLAG_COLOR)) { + flags_arr.push_back("FLAG_EMIT_COLOR"); + } + if (has_flag(EmitFlags::EMIT_FLAG_CUSTOM)) { + flags_arr.push_back("FLAG_EMIT_CUSTOM"); + } + + String flags; + + for (int i = 0; i < flags_arr.size(); i++) { + if (i > 0) { + flags += "|"; + } + flags += flags_arr[i]; + } + + if (flags.is_empty()) { + flags = "uint(0)"; + } + + if (!default_condition) { + code += "\tif (" + p_input_vars[0] + ") {\n"; + } + + code += tab + "emit_subparticle(" + transform + ", " + velocity + ", vec4(" + color + ", " + alpha + "), vec4(" + custom + ", " + custom_alpha + "), " + flags + ");\n"; + + if (!default_condition) { + code += "\t}\n"; + } + + return code; +} + +VisualShaderNodeParticleEmit::VisualShaderNodeParticleEmit() { + set_input_port_default_value(0, true); +} diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h new file mode 100644 index 0000000000..ecd187a885 --- /dev/null +++ b/scene/resources/visual_shader_particle_nodes.h @@ -0,0 +1,285 @@ +/*************************************************************************/ +/* visual_shader_particle_nodes.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VISUAL_SHADER_PARTICLE_NODES_H +#define VISUAL_SHADER_PARTICLE_NODES_H + +#include "scene/resources/visual_shader.h" + +// Emit nodes + +class VisualShaderNodeParticleEmitter : public VisualShaderNode { + GDCLASS(VisualShaderNodeParticleEmitter, VisualShaderNode); + +public: + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + VisualShaderNodeParticleEmitter(); +}; + +class VisualShaderNodeParticleSphereEmitter : public VisualShaderNodeParticleEmitter { + GDCLASS(VisualShaderNodeParticleSphereEmitter, VisualShaderNodeParticleEmitter); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleSphereEmitter(); +}; + +class VisualShaderNodeParticleBoxEmitter : public VisualShaderNodeParticleEmitter { + GDCLASS(VisualShaderNodeParticleBoxEmitter, VisualShaderNodeParticleEmitter); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleBoxEmitter(); +}; + +class VisualShaderNodeParticleRingEmitter : public VisualShaderNodeParticleEmitter { + GDCLASS(VisualShaderNodeParticleRingEmitter, VisualShaderNodeParticleEmitter); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleRingEmitter(); +}; + +class VisualShaderNodeParticleMultiplyByAxisAngle : public VisualShaderNode { + GDCLASS(VisualShaderNodeParticleMultiplyByAxisAngle, VisualShaderNode); + bool degrees_mode = true; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + virtual bool is_show_prop_names() const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + void set_degrees_mode(bool p_enabled); + bool is_degrees_mode() const; + Vector<StringName> get_editable_properties() const override; + + VisualShaderNodeParticleMultiplyByAxisAngle(); +}; + +class VisualShaderNodeParticleConeVelocity : public VisualShaderNode { + GDCLASS(VisualShaderNodeParticleConeVelocity, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleConeVelocity(); +}; + +class VisualShaderNodeParticleRandomness : public VisualShaderNode { + GDCLASS(VisualShaderNodeParticleRandomness, VisualShaderNode); + +public: + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_MAX, + }; + +private: + OpType op_type = OP_TYPE_SCALAR; + +protected: + static void _bind_methods(); + +public: + Vector<StringName> get_editable_properties() const override; + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + void set_op_type(OpType p_type); + OpType get_op_type() const; + + VisualShaderNodeParticleRandomness(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeParticleRandomness::OpType) + +// Process nodes + +class VisualShaderNodeParticleAccelerator : public VisualShaderNodeOutput { + GDCLASS(VisualShaderNodeParticleAccelerator, VisualShaderNodeOutput); + +public: + enum Mode { + MODE_LINEAR, + MODE_RADIAL, + MODE_TANGENTIAL, + MODE_MAX, + }; + +private: + Mode mode = MODE_LINEAR; + +protected: + static void _bind_methods(); + +public: + Vector<StringName> get_editable_properties() const override; + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + void set_mode(Mode p_mode); + Mode get_mode() const; + + VisualShaderNodeParticleAccelerator(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeParticleAccelerator::Mode) + +// Common nodes + +class VisualShaderNodeParticleOutput : public VisualShaderNodeOutput { + GDCLASS(VisualShaderNodeParticleOutput, VisualShaderNodeOutput); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + virtual bool is_port_separator(int p_index) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleOutput(); +}; + +class VisualShaderNodeParticleEmit : public VisualShaderNode { + GDCLASS(VisualShaderNodeParticleEmit, VisualShaderNode); + +public: + enum EmitFlags { + EMIT_FLAG_POSITION = 1, + EMIT_FLAG_ROT_SCALE = 2, + EMIT_FLAG_VELOCITY = 4, + EMIT_FLAG_COLOR = 8, + EMIT_FLAG_CUSTOM = 16, + }; + +protected: + int flags = EMIT_FLAG_POSITION | EMIT_FLAG_ROT_SCALE | EMIT_FLAG_VELOCITY | EMIT_FLAG_COLOR | EMIT_FLAG_CUSTOM; + static void _bind_methods(); + +public: + Vector<StringName> get_editable_properties() const override; + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + void add_flag(EmitFlags p_flag); + bool has_flag(EmitFlags p_flag) const; + + void set_flags(EmitFlags p_flags); + EmitFlags get_flags() const; + + virtual bool is_show_prop_names() const override; + virtual bool is_generate_input_var(int p_port) const override; + virtual String get_input_port_default_hint(int p_port) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeParticleEmit(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeParticleEmit::EmitFlags) + +#endif diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index 7df2f99f67..1d97de5205 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -290,7 +290,7 @@ void Reverb::update_parameters() { c.feedback = (room_offset + room_scale); } - float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough) + float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough) auxdmp *= auxdmp; c.damp = expf(-Math_TAU * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz diff --git a/servers/display_server.cpp b/servers/display_server.cpp index c7d444c993..ded4b849ef 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -509,6 +509,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED); BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED); + BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN); BIND_CONSTANT(SCREEN_OF_MAIN_WINDOW); BIND_CONSTANT(MAIN_WINDOW_ID); diff --git a/servers/display_server.h b/servers/display_server.h index c108281aff..b8201f6fd5 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -142,7 +142,8 @@ public: MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED + MOUSE_MODE_CONFINED, + MOUSE_MODE_CONFINED_HIDDEN, }; virtual void mouse_set_mode(MouseMode p_mode); diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 9e32bc209b..ef2635c188 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "servers/navigation_server_2d.h" -#include "core/math/transform.h" #include "core/math/transform_2d.h" +#include "core/math/transform_3d.h" #include "servers/navigation_server_3d.h" /** @@ -129,12 +129,12 @@ static Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) { return nd; } -static Transform trf2_to_trf3(const Transform2D &d) { +static Transform3D trf2_to_trf3(const Transform2D &d) { Vector3 o(v2_to_v3(d.get_origin())); Basis b; b.rotate(Vector3(0, -1, 0), d.get_rotation()); b.scale(v2_to_v3(d.get_scale())); - return Transform(b, o); + return Transform3D(b, o); } static Object *obj_to_obj(Object *d) { diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 420f9c9c18..3aef693ac8 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -106,7 +106,7 @@ public: virtual uint32_t region_get_layers(RID p_region) const = 0; /// Set the global transformation of this region. - virtual void region_set_transform(RID p_region, Transform p_transform) const = 0; + virtual void region_set_transform(RID p_region, Transform3D p_transform) const = 0; /// Set the navigation mesh of this region. virtual void region_set_navmesh(RID p_region, Ref<NavigationMesh> p_nav_mesh) const = 0; diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index f78a487e27..6f244deb1e 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -43,7 +43,7 @@ void Body2DSW::update_inertias() { //update shapes and motions switch (mode) { - case PhysicsServer2D::BODY_MODE_RIGID: { + case PhysicsServer2D::BODY_MODE_DYNAMIC: { if (user_inertia) { _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0; break; @@ -87,7 +87,7 @@ void Body2DSW::update_inertias() { _inv_inertia = 0; _inv_mass = 0; } break; - case PhysicsServer2D::BODY_MODE_CHARACTER: { + case PhysicsServer2D::BODY_MODE_DYNAMIC_LOCKED: { _inv_inertia = 0; _inv_mass = 1.0 / mass; @@ -204,14 +204,14 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { first_time_kinematic = true; } } break; - case PhysicsServer2D::BODY_MODE_RIGID: { + case PhysicsServer2D::BODY_MODE_DYNAMIC: { _inv_mass = mass > 0 ? (1.0 / mass) : 0; _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0; _set_static(false); set_active(true); } break; - case PhysicsServer2D::BODY_MODE_CHARACTER: { + case PhysicsServer2D::BODY_MODE_DYNAMIC_LOCKED: { _inv_mass = mass > 0 ? (1.0 / mass) : 0; _inv_inertia = 0; _set_static(false); @@ -219,7 +219,7 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { angular_velocity = 0; } break; } - if (p_mode == PhysicsServer2D::BODY_MODE_RIGID && _inv_inertia == 0) { + if (p_mode == PhysicsServer2D::BODY_MODE_DYNAMIC && _inv_inertia == 0) { _update_inertia(); } /* @@ -267,25 +267,16 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va } break; case PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY: { - /* - if (mode==PhysicsServer2D::BODY_MODE_STATIC) - break; - */ linear_velocity = p_variant; wakeup(); } break; case PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY: { - /* - if (mode!=PhysicsServer2D::BODY_MODE_RIGID) - break; - */ angular_velocity = p_variant; wakeup(); } break; case PhysicsServer2D::BODY_STATE_SLEEPING: { - //? if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { break; } @@ -304,7 +295,7 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va } break; case PhysicsServer2D::BODY_STATE_CAN_SLEEP: { can_sleep = p_variant; - if (mode == PhysicsServer2D::BODY_MODE_RIGID && !active && !can_sleep) { + if (mode == PhysicsServer2D::BODY_MODE_DYNAMIC && !active && !can_sleep) { set_active(true); } @@ -551,7 +542,7 @@ void Body2DSW::wakeup_neighbours() { continue; } Body2DSW *b = n[i]; - if (b->mode != PhysicsServer2D::BODY_MODE_RIGID) { + if (b->mode != PhysicsServer2D::BODY_MODE_DYNAMIC) { continue; } @@ -588,9 +579,7 @@ void Body2DSW::call_queries() { bool Body2DSW::sleep_test(real_t p_step) { if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { - return true; // - } else if (mode == PhysicsServer2D::BODY_MODE_CHARACTER) { - return !active; // characters and kinematic bodies don't sleep unless asked to sleep + return true; } else if (!can_sleep) { return false; } @@ -623,7 +612,7 @@ Body2DSW::Body2DSW() : active_list(this), inertia_update_list(this), direct_state_query_list(this) { - mode = PhysicsServer2D::BODY_MODE_RIGID; + mode = PhysicsServer2D::BODY_MODE_DYNAMIC; active = true; angular_velocity = 0; biased_angular_velocity = 0; diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index eaec582f9b..5a0a628fbc 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -322,7 +322,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) { Vector2 delta = (B->get_transform().get_origin() + rB) - (A->get_transform().get_origin() + rA); real_t _b = get_bias(); - gbias = (delta * -(_b == 0 ? space->get_constraint_bias() : _b) * (1.0 / p_step)).clamped(get_max_bias()); + gbias = (delta * -(_b == 0 ? space->get_constraint_bias() : _b) * (1.0 / p_step)).limit_length(get_max_bias()); correct = true; return true; @@ -348,7 +348,7 @@ void GrooveJoint2DSW::solve(real_t p_step) { Vector2 jOld = jn_acc; j += jOld; - jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : j.project(xf_normal)).clamped(jn_max); + jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : j.project(xf_normal)).limit_length(jn_max); j = jn_acc - jOld; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index f1eb78a776..5002bf5fc8 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -247,8 +247,8 @@ public: virtual void body_set_pickable(RID p_body, bool p_pickable) override; - virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; + virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; + virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.08) override; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 790c87cc44..930b19c2cb 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -56,7 +56,7 @@ void PhysicsServer2DWrapMT::thread_loop() { step_thread_up.set(); while (!exit.is_set()) { // flush commands one by one, until exit is requested - command_queue.wait_and_flush_one(); + command_queue.wait_and_flush(); } command_queue.flush_all(); // flush all diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 4f12248c3e..1380e57b57 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -827,7 +827,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); - if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_RIGID) { + if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_DYNAMIC) { //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction Vector2 lv = b->get_linear_velocity(); //compute displacement from linear velocity @@ -1109,7 +1109,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) { const Body2DSW *b = static_cast<const Body2DSW *>(col_obj); - if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_RIGID) { + if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_DYNAMIC) { //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction Vector2 lv = b->get_linear_velocity(); //compute displacement from linear velocity diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp index bb4e0ed752..a9f5c4aec3 100644 --- a/servers/physics_3d/area_3d_sw.cpp +++ b/servers/physics_3d/area_3d_sw.cpp @@ -52,7 +52,7 @@ void Area3DSW::_shapes_changed() { } } -void Area3DSW::set_transform(const Transform &p_transform) { +void Area3DSW::set_transform(const Transform3D &p_transform) { if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); } diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h index 8a0a1e963b..12f7545c08 100644 --- a/servers/physics_3d/area_3d_sw.h +++ b/servers/physics_3d/area_3d_sw.h @@ -156,7 +156,7 @@ public: void set_monitorable(bool p_monitorable); _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } - void set_transform(const Transform &p_transform); + void set_transform(const Transform3D &p_transform); void set_space(Space3DSW *p_space); diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp index e4f9548a61..ea6064cb4c 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/body_3d_sw.cpp @@ -54,7 +54,7 @@ void Body3DSW::update_inertias() { // Update shapes and motions. switch (mode) { - case PhysicsServer3D::BODY_MODE_RIGID: { + case PhysicsServer3D::BODY_MODE_DYNAMIC: { // Update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet) real_t total_area = 0; @@ -100,7 +100,7 @@ void Body3DSW::update_inertias() { real_t mass = area * this->mass / total_area; Basis shape_inertia_tensor = shape->get_moment_of_inertia(mass).to_diagonal_matrix(); - Transform shape_transform = get_shape_transform(i); + Transform3D shape_transform = get_shape_transform(i); Basis shape_basis = shape_transform.basis.orthonormalized(); // NOTE: we don't take the scale of collision shapes into account when computing the inertia tensor! @@ -132,7 +132,7 @@ void Body3DSW::update_inertias() { _inv_inertia_tensor.set_zero(); _inv_mass = 0; } break; - case PhysicsServer3D::BODY_MODE_CHARACTER: { + case PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED: { _inv_inertia_tensor.set_zero(); _inv_mass = 1.0 / mass; @@ -239,13 +239,13 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { } } break; - case PhysicsServer3D::BODY_MODE_RIGID: { + case PhysicsServer3D::BODY_MODE_DYNAMIC: { _inv_mass = mass > 0 ? (1.0 / mass) : 0; _set_static(false); set_active(true); } break; - case PhysicsServer3D::BODY_MODE_CHARACTER: { + case PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED: { _inv_mass = mass > 0 ? (1.0 / mass) : 0; _set_static(false); set_active(true); @@ -286,7 +286,7 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va _set_inv_transform(get_transform().affine_inverse()); wakeup_neighbours(); } else { - Transform t = p_variant; + Transform3D t = p_variant; t.orthonormalize(); new_transform = get_transform(); //used as old to compute motion if (new_transform == t) { @@ -299,24 +299,15 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } break; case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: { - /* - if (mode==PhysicsServer3D::BODY_MODE_STATIC) - break; - */ linear_velocity = p_variant; wakeup(); } break; case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: { - /* - if (mode!=PhysicsServer3D::BODY_MODE_RIGID) - break; - */ angular_velocity = p_variant; wakeup(); } break; case PhysicsServer3D::BODY_STATE_SLEEPING: { - //? if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { break; } @@ -333,7 +324,7 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } break; case PhysicsServer3D::BODY_STATE_CAN_SLEEP: { can_sleep = p_variant; - if (mode == PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep) { + if (mode == PhysicsServer3D::BODY_MODE_DYNAMIC && !active && !can_sleep) { set_active(true); } @@ -585,7 +576,7 @@ void Body3DSW::integrate_velocities(real_t p_step) { Vector3 total_angular_velocity = angular_velocity + biased_angular_velocity; real_t ang_vel = total_angular_velocity.length(); - Transform transform = get_transform(); + Transform3D transform = get_transform(); if (ang_vel != 0.0) { Vector3 ang_vel_axis = total_angular_velocity / ang_vel; @@ -617,8 +608,8 @@ void Body3DSW::integrate_velocities(real_t p_step) { } /* -void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) { - Transform inv_xform = p_xform.affine_inverse(); +void BodySW::simulate_motion(const Transform3D& p_xform,real_t p_step) { + Transform3D inv_xform = p_xform.affine_inverse(); if (!get_space()) { _set_transform(p_xform); _set_inv_transform(inv_xform); @@ -659,7 +650,7 @@ void Body3DSW::wakeup_neighbours() { continue; } Body3DSW *b = n[i]; - if (b->mode != PhysicsServer3D::BODY_MODE_RIGID) { + if (b->mode != PhysicsServer3D::BODY_MODE_DYNAMIC) { continue; } @@ -693,9 +684,7 @@ void Body3DSW::call_queries() { bool Body3DSW::sleep_test(real_t p_step) { if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { - return true; // - } else if (mode == PhysicsServer3D::BODY_MODE_CHARACTER) { - return !active; // characters don't sleep unless asked to sleep + return true; } else if (!can_sleep) { return false; } @@ -723,22 +712,16 @@ void Body3DSW::set_force_integration_callback(const Callable &p_callable, const } } -void Body3DSW::set_kinematic_margin(real_t p_margin) { - kinematic_safe_margin = p_margin; -} - Body3DSW::Body3DSW() : CollisionObject3DSW(TYPE_BODY), active_list(this), inertia_update_list(this), direct_state_query_list(this) { - mode = PhysicsServer3D::BODY_MODE_RIGID; + mode = PhysicsServer3D::BODY_MODE_DYNAMIC; active = true; mass = 1; - kinematic_safe_margin = 0.001; - //_inv_inertia=Transform(); _inv_mass = 1; bounce = 0; friction = 1; diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index 9afb8cd56f..0fa31c5037 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -55,7 +55,6 @@ class Body3DSW : public CollisionObject3DSW { uint16_t locked_axis = 0; - real_t kinematic_safe_margin; real_t _inv_mass; Vector3 _inv_inertia; // Relative to the principal axes of inertia @@ -93,7 +92,7 @@ class Body3DSW : public CollisionObject3DSW { bool first_time_kinematic; void _update_inertia(); virtual void _shapes_changed(); - Transform new_transform; + Transform3D new_transform; Map<Constraint3DSW *, int> constraint_map; @@ -144,9 +143,6 @@ class Body3DSW : public CollisionObject3DSW { public: void set_force_integration_callback(const Callable &p_callable, const Variant &p_udata = Variant()); - void set_kinematic_margin(real_t p_margin); - _FORCE_INLINE_ real_t get_kinematic_margin() { return kinematic_safe_margin; } - _FORCE_INLINE_ void add_area(Area3DSW *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { @@ -311,7 +307,7 @@ public: return p_axis.dot(_inv_inertia_tensor.xform_inv(p_axis)); } - //void simulate_motion(const Transform& p_xform,real_t p_step); + //void simulate_motion(const Transform3D& p_xform,real_t p_step); void call_queries(); void wakeup_neighbours(); @@ -390,8 +386,8 @@ public: virtual void set_angular_velocity(const Vector3 &p_velocity) override { body->set_angular_velocity(p_velocity); } virtual Vector3 get_angular_velocity() const override { return body->get_angular_velocity(); } - virtual void set_transform(const Transform &p_transform) override { body->set_state(PhysicsServer3D::BODY_STATE_TRANSFORM, p_transform); } - virtual Transform get_transform() const override { return body->get_transform(); } + virtual void set_transform(const Transform3D &p_transform) override { body->set_state(PhysicsServer3D::BODY_STATE_TRANSFORM, p_transform); } + virtual Transform3D get_transform() const override { return body->get_transform(); } virtual void add_central_force(const Vector3 &p_force) override { body->add_central_force(p_force); } virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override { diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/body_pair_3d_sw.cpp index cdb3da665e..aed4815c5e 100644 --- a/servers/physics_3d/body_pair_3d_sw.cpp +++ b/servers/physics_3d/body_pair_3d_sw.cpp @@ -161,7 +161,7 @@ void BodyPair3DSW::validate_contacts() { } } -bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform &p_xform_B) { +bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform3D &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform3D &p_xform_B) { Vector3 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); if (mlen < CMP_EPSILON) { @@ -184,7 +184,7 @@ bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Vector3 from = p_xform_A.xform(s); Vector3 to = from + motion; - Transform from_inv = p_xform_B.affine_inverse(); + Transform3D from_inv = p_xform_B.affine_inverse(); Vector3 local_from = from_inv.xform(from - mnormal * mlen * 0.1); //start from a little inside the bounding box Vector3 local_to = from_inv.xform(to); @@ -240,12 +240,12 @@ bool BodyPair3DSW::setup(real_t p_step) { validate_contacts(); const Vector3 &offset_A = A->get_transform().get_origin(); - Transform xform_Au = Transform(A->get_transform().basis, Vector3()); - Transform xform_A = xform_Au * A->get_shape_transform(shape_A); + Transform3D xform_Au = Transform3D(A->get_transform().basis, Vector3()); + Transform3D xform_A = xform_Au * A->get_shape_transform(shape_A); - Transform xform_Bu = B->get_transform(); + Transform3D xform_Bu = B->get_transform(); xform_Bu.origin -= offset_A; - Transform xform_B = xform_Bu * B->get_shape_transform(shape_B); + Transform3D xform_B = xform_Bu * B->get_shape_transform(shape_B); Shape3DSW *shape_A_ptr = A->get_shape(shape_A); Shape3DSW *shape_B_ptr = B->get_shape(shape_B); @@ -571,7 +571,7 @@ void BodySoftBodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, int void BodySoftBodyPair3DSW::validate_contacts() { // Make sure to erase contacts that are no longer valid. - const Transform &transform_A = body->get_transform(); + const Transform3D &transform_A = body->get_transform(); real_t contact_max_separation = space->get_contact_max_separation(); @@ -612,11 +612,11 @@ bool BodySoftBodyPair3DSW::setup(real_t p_step) { return false; } - const Transform &xform_Au = body->get_transform(); - Transform xform_A = xform_Au * body->get_shape_transform(body_shape); + const Transform3D &xform_Au = body->get_transform(); + Transform3D xform_A = xform_Au * body->get_shape_transform(body_shape); - Transform xform_Bu = soft_body->get_transform(); - Transform xform_B = xform_Bu * soft_body->get_shape_transform(0); + Transform3D xform_Bu = soft_body->get_transform(); + Transform3D xform_B = xform_Bu * soft_body->get_shape_transform(0); validate_contacts(); @@ -647,7 +647,7 @@ bool BodySoftBodyPair3DSW::pre_solve(real_t p_step) { bool do_process = false; - const Transform &transform_A = body->get_transform(); + const Transform3D &transform_A = body->get_transform(); uint32_t contact_count = contacts.size(); for (uint32_t contact_index = 0; contact_index < contact_count; ++contact_index) { diff --git a/servers/physics_3d/body_pair_3d_sw.h b/servers/physics_3d/body_pair_3d_sw.h index 3f425ba2d7..976982d1f1 100644 --- a/servers/physics_3d/body_pair_3d_sw.h +++ b/servers/physics_3d/body_pair_3d_sw.h @@ -98,7 +98,7 @@ class BodyPair3DSW : public BodyContact3DSW { void contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B); void validate_contacts(); - bool _test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform &p_xform_B); + bool _test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform3D &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform3D &p_xform_B); public: virtual bool setup(real_t p_step) override; diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index 459deb1356..51e2432071 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -32,7 +32,7 @@ #include "servers/physics_3d/physics_server_3d_sw.h" #include "space_3d_sw.h" -void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_transform, bool p_disabled) { +void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform3D &p_transform, bool p_disabled) { Shape s; s.shape = p_shape; s.xform = p_transform; @@ -62,7 +62,7 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { //_shapes_changed(); } -void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_transform) { +void CollisionObject3DSW::set_shape_transform(int p_index, const Transform3D &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].xform = p_transform; @@ -149,7 +149,7 @@ void CollisionObject3DSW::_update_shapes() { //not quite correct, should compute the next matrix.. AABB shape_aabb = s.shape->get_aabb(); - Transform xform = transform * s.xform; + Transform3D xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); shape_aabb.grow_by((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); s.aabb_cache = shape_aabb; @@ -176,7 +176,7 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { //not quite correct, should compute the next matrix.. AABB shape_aabb = s.shape->get_aabb(); - Transform xform = transform * s.xform; + Transform3D xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); shape_aabb.merge_with(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion s.aabb_cache = shape_aabb; diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h index 85221b7746..5505fec3da 100644 --- a/servers/physics_3d/collision_object_3d_sw.h +++ b/servers/physics_3d/collision_object_3d_sw.h @@ -60,8 +60,8 @@ private: uint32_t collision_mask; struct Shape { - Transform xform; - Transform xform_inv; + Transform3D xform; + Transform3D xform_inv; BroadPhase3DSW::ID bpid; AABB aabb_cache; //for rayqueries real_t area_cache; @@ -73,8 +73,8 @@ private: Vector<Shape> shapes; Space3DSW *space; - Transform transform; - Transform inv_transform; + Transform3D transform; + Transform3D inv_transform; bool _static; SelfList<CollisionObject3DSW> pending_shape_update_list; @@ -85,7 +85,7 @@ protected: void _update_shapes_with_motion(const Vector3 &p_motion); void _unregister_shapes(); - _FORCE_INLINE_ void _set_transform(const Transform &p_transform, bool p_update_shapes = true) { + _FORCE_INLINE_ void _set_transform(const Transform3D &p_transform, bool p_update_shapes = true) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(p_transform.origin.length_squared() > MAX_OBJECT_DISTANCE_X2, "Object went too far away (more than '" + itos(MAX_OBJECT_DISTANCE) + "' units from origin)."); @@ -96,7 +96,7 @@ protected: _update_shapes(); } } - _FORCE_INLINE_ void _set_inv_transform(const Transform &p_transform) { inv_transform = p_transform; } + _FORCE_INLINE_ void _set_inv_transform(const Transform3D &p_transform) { inv_transform = p_transform; } void _set_static(bool p_static); virtual void _shapes_changed() = 0; @@ -116,22 +116,22 @@ public: void _shape_changed(); _FORCE_INLINE_ Type get_type() const { return type; } - void add_shape(Shape3DSW *p_shape, const Transform &p_transform = Transform(), bool p_disabled = false); + void add_shape(Shape3DSW *p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false); void set_shape(int p_index, Shape3DSW *p_shape); - void set_shape_transform(int p_index, const Transform &p_transform); + void set_shape_transform(int p_index, const Transform3D &p_transform); _FORCE_INLINE_ int get_shape_count() const { return shapes.size(); } _FORCE_INLINE_ bool is_shape_disabled(int p_index) const { CRASH_BAD_INDEX(p_index, shapes.size()); return shapes[p_index].disabled; } _FORCE_INLINE_ Shape3DSW *get_shape(int p_index) const { return shapes[p_index].shape; } - _FORCE_INLINE_ const Transform &get_shape_transform(int p_index) const { return shapes[p_index].xform; } - _FORCE_INLINE_ const Transform &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; } + _FORCE_INLINE_ const Transform3D &get_shape_transform(int p_index) const { return shapes[p_index].xform; } + _FORCE_INLINE_ const Transform3D &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; } _FORCE_INLINE_ const AABB &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } _FORCE_INLINE_ real_t get_shape_area(int p_index) const { return shapes[p_index].area_cache; } - _FORCE_INLINE_ const Transform &get_transform() const { return transform; } - _FORCE_INLINE_ const Transform &get_inv_transform() const { return inv_transform; } + _FORCE_INLINE_ const Transform3D &get_transform() const { return transform; } + _FORCE_INLINE_ const Transform3D &get_inv_transform() const { return inv_transform; } _FORCE_INLINE_ Space3DSW *get_space() const { return space; } _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; } diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index fcac0587b2..b362f1ff17 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -608,8 +608,8 @@ template <class ShapeA, class ShapeB, bool withMargin = false> class SeparatorAxisTest { const ShapeA *shape_A; const ShapeB *shape_B; - const Transform *transform_A; - const Transform *transform_B; + const Transform3D *transform_A; + const Transform3D *transform_B; real_t best_depth; Vector3 best_axis; _CollectorCallback *callback; @@ -750,7 +750,7 @@ public: callback->collided = true; } - _FORCE_INLINE_ SeparatorAxisTest(const ShapeA *p_shape_A, const Transform &p_transform_A, const ShapeB *p_shape_B, const Transform &p_transform_B, _CollectorCallback *p_callback, real_t p_margin_A = 0, real_t p_margin_B = 0) { + _FORCE_INLINE_ SeparatorAxisTest(const ShapeA *p_shape_A, const Transform3D &p_transform_A, const ShapeB *p_shape_B, const Transform3D &p_transform_B, _CollectorCallback *p_callback, real_t p_margin_A = 0, real_t p_margin_B = 0) { best_depth = 1e15; shape_A = p_shape_A; shape_B = p_shape_B; @@ -764,10 +764,10 @@ public: /****** SAT TESTS *******/ -typedef void (*CollisionFunc)(const Shape3DSW *, const Transform &, const Shape3DSW *, const Transform &, _CollectorCallback *p_callback, real_t, real_t); +typedef void (*CollisionFunc)(const Shape3DSW *, const Transform3D &, const Shape3DSW *, const Transform3D &, _CollectorCallback *p_callback, real_t, real_t); template <bool withMargin> -static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const SphereShape3DSW *sphere_B = static_cast<const SphereShape3DSW *>(p_b); @@ -787,7 +787,7 @@ static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_tr } template <bool withMargin> -static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_box(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); @@ -838,7 +838,7 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_trans } template <bool withMargin> -static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); @@ -880,7 +880,7 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t } template <bool withMargin> -static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); @@ -939,7 +939,7 @@ static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_ } template <bool withMargin> -static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); @@ -999,7 +999,7 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo } template <bool withMargin> -static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_sphere_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -1044,7 +1044,7 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_tran } template <bool withMargin> -static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_box_box(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); @@ -1142,7 +1142,7 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transfor } template <bool withMargin> -static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_box_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); @@ -1240,7 +1240,7 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran } template <bool withMargin> -static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); @@ -1353,7 +1353,7 @@ static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_tra } template <bool withMargin> -static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); @@ -1468,7 +1468,7 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform } template <bool withMargin> -static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_box_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -1591,7 +1591,7 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo } template <bool withMargin> -static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); @@ -1655,7 +1655,7 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_ } template <bool withMargin> -static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); @@ -1717,7 +1717,7 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p } template <bool withMargin> -static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); @@ -1781,7 +1781,7 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf } template <bool withMargin> -static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_capsule_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -1855,7 +1855,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra } template <bool withMargin> -static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); @@ -1909,7 +1909,7 @@ static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform & } template <bool withMargin> -static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); @@ -1926,7 +1926,7 @@ static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Trans } template <bool withMargin> -static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -2031,7 +2031,7 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_tr } template <bool withMargin> -static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); @@ -2140,7 +2140,7 @@ static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const } template <bool withMargin> -static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { +static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform3D &p_transform_a, const Shape3DSW *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -2258,7 +2258,7 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform separator.generate_contacts(); } -bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) { +bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) { PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_PLANE, false); @@ -2358,8 +2358,8 @@ bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_tr const Shape3DSW *A = p_shape_A; const Shape3DSW *B = p_shape_B; - const Transform *transform_A = &p_transform_A; - const Transform *transform_B = &p_transform_B; + const Transform3D *transform_A = &p_transform_A; + const Transform3D *transform_B = &p_transform_B; real_t margin_A = p_margin_a; real_t margin_B = p_margin_b; diff --git a/servers/physics_3d/collision_solver_3d_sat.h b/servers/physics_3d/collision_solver_3d_sat.h index 97454c0b4a..e50da7b101 100644 --- a/servers/physics_3d/collision_solver_3d_sat.h +++ b/servers/physics_3d/collision_solver_3d_sat.h @@ -33,6 +33,6 @@ #include "collision_solver_3d_sw.h" -bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); +bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); #endif // COLLISION_SOLVER_SAT_H diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index f655c4626c..67330d497e 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -37,7 +37,7 @@ #define collision_solver sat_calculate_penetration //#define collision_solver gjk_epa_calculate_penetration -bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { +bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) { return false; @@ -89,14 +89,14 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T return found; } -bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { +bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { const RayShape3DSW *ray = static_cast<const RayShape3DSW *>(p_shape_A); Vector3 from = p_transform_A.origin; Vector3 to = from + p_transform_A.basis.get_axis(2) * ray->get_length(); Vector3 support_A = to; - Transform ai = p_transform_B.affine_inverse(); + Transform3D ai = p_transform_B.affine_inverse(); from = ai.xform(from); to = ai.xform(to); @@ -146,8 +146,8 @@ struct _SoftBodyQueryInfo { SoftBody3DSW *soft_body = nullptr; const Shape3DSW *shape_A = nullptr; const Shape3DSW *shape_B = nullptr; - Transform transform_A; - Transform node_transform; + Transform3D transform_A; + Transform3D node_transform; _SoftBodyContactCollisionInfo contact_info; #ifdef DEBUG_ENABLED int node_query_count = 0; @@ -160,7 +160,7 @@ bool CollisionSolver3DSW::soft_body_query_callback(uint32_t p_node_index, void * Vector3 node_position = query_cinfo.soft_body->get_node_position(p_node_index); - Transform transform_B; + Transform3D transform_B; transform_B.origin = query_cinfo.node_transform.xform(node_position); query_cinfo.contact_info.node_index = p_node_index; @@ -201,11 +201,11 @@ void CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW #endif } -bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { +bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { const SoftBodyShape3DSW *soft_body_shape_B = static_cast<const SoftBodyShape3DSW *>(p_shape_B); SoftBody3DSW *soft_body = soft_body_shape_B->get_soft_body(); - const Transform &world_to_local = soft_body->get_inv_transform(); + const Transform3D &world_to_local = soft_body->get_inv_transform(); const real_t collision_margin = soft_body->get_collision_margin(); @@ -257,9 +257,9 @@ bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Tran } struct _ConcaveCollisionInfo { - const Transform *transform_A; + const Transform3D *transform_A; const Shape3DSW *shape_A; - const Transform *transform_B; + const Transform3D *transform_B; CollisionSolver3DSW::CallbackResult result_callback; void *userdata; bool swap_result; @@ -285,7 +285,7 @@ void CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex cinfo.collisions++; } -bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) { +bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) { const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B); _ConcaveCollisionInfo cinfo; @@ -302,7 +302,7 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf cinfo.aabb_tests = 0; - Transform rel_transform = p_transform_A; + Transform3D rel_transform = p_transform_A; rel_transform.origin -= p_transform_B.origin; //quickly compute a local AABB @@ -329,7 +329,7 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf return cinfo.collided; } -bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { +bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); PhysicsServer3D::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); @@ -421,7 +421,7 @@ void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW cinfo.collisions++; } -bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) { +bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) { const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A); if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) { return false; @@ -473,7 +473,7 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const return collided; } -bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { +bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { if (p_shape_A->is_concave()) { return false; } @@ -504,7 +504,7 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans cinfo.aabb_tests = 0; cinfo.tested = false; - Transform rel_transform = p_transform_A; + Transform3D rel_transform = p_transform_A; rel_transform.origin -= p_transform_B.origin; //quickly compute a local AABB diff --git a/servers/physics_3d/collision_solver_3d_sw.h b/servers/physics_3d/collision_solver_3d_sw.h index 34ac2c6d3f..a5dd7d48eb 100644 --- a/servers/physics_3d/collision_solver_3d_sw.h +++ b/servers/physics_3d/collision_solver_3d_sw.h @@ -42,16 +42,16 @@ private: static void soft_body_contact_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B, void *p_userdata); static void soft_body_concave_callback(void *p_userdata, Shape3DSW *p_convex); static void concave_callback(void *p_userdata, Shape3DSW *p_convex); - static bool solve_static_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool solve_ray(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool solve_soft_body(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); - static bool solve_concave(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_static_plane(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_ray(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_soft_body(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result); + static bool solve_concave(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A = 0, real_t p_margin_B = 0); static void concave_distance_callback(void *p_userdata, Shape3DSW *p_convex); - static bool solve_distance_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B); + static bool solve_distance_plane(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B); public: - static bool solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = nullptr); + static bool solve_static(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = nullptr, real_t p_margin_A = 0, real_t p_margin_B = 0); + static bool solve_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = nullptr); }; #endif // COLLISION_SOLVER__SW_H diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index 1a8c7f704f..2df991563d 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -107,16 +107,16 @@ typedef unsigned char U1; struct MinkowskiDiff { const Shape3DSW* m_shapes[2]; - Transform transform_A; - Transform transform_B; + Transform3D transform_A; + Transform3D transform_B; real_t margin_A = 0.0; real_t margin_B = 0.0; Vector3 (*get_support)(const Shape3DSW*, const Vector3&, real_t); - void Initialize(const Shape3DSW* shape0, const Transform& wtrs0, const real_t margin0, - const Shape3DSW* shape1, const Transform& wtrs1, const real_t margin1) { + void Initialize(const Shape3DSW* shape0, const Transform3D& wtrs0, const real_t margin0, + const Shape3DSW* shape1, const Transform3D& wtrs1, const real_t margin1) { m_shapes[0] = shape0; m_shapes[1] = shape1; transform_A = wtrs0; @@ -862,8 +862,8 @@ struct GJK }; // - static void Initialize( const Shape3DSW* shape0, const Transform& wtrs0, real_t margin0, - const Shape3DSW* shape1, const Transform& wtrs1, real_t margin1, + static void Initialize( const Shape3DSW* shape0, const Transform3D& wtrs0, real_t margin0, + const Shape3DSW* shape1, const Transform3D& wtrs1, real_t margin1, sResults& results, tShape& shape) { @@ -885,10 +885,10 @@ struct GJK // bool Distance( const Shape3DSW* shape0, - const Transform& wtrs0, + const Transform3D& wtrs0, real_t margin0, const Shape3DSW* shape1, - const Transform& wtrs1, + const Transform3D& wtrs1, real_t margin1, const Vector3& guess, sResults& results) @@ -926,10 +926,10 @@ bool Distance( const Shape3DSW* shape0, // bool Penetration( const Shape3DSW* shape0, - const Transform& wtrs0, + const Transform3D& wtrs0, real_t margin0, const Shape3DSW* shape1, - const Transform& wtrs1, + const Transform3D& wtrs1, real_t margin1, const Vector3& guess, sResults& results @@ -993,7 +993,7 @@ bool Penetration( const Shape3DSW* shape0, /* clang-format on */ -bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) { +bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) { GjkEpa2::sResults res; if (GjkEpa2::Distance(p_shape_A, p_transform_A, 0.0, p_shape_B, p_transform_B, 0.0, p_transform_B.origin - p_transform_A.origin, res)) { @@ -1005,7 +1005,7 @@ bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_t return false; } -bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, real_t p_margin_A, real_t p_margin_B) { +bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, real_t p_margin_A, real_t p_margin_B) { GjkEpa2::sResults res; if (GjkEpa2::Penetration(p_shape_A, p_transform_A, p_margin_A, p_shape_B, p_transform_B, p_margin_B, p_transform_B.origin - p_transform_A.origin, res)) { diff --git a/servers/physics_3d/gjk_epa.h b/servers/physics_3d/gjk_epa.h index a7e2e1719e..69e85d2bc0 100644 --- a/servers/physics_3d/gjk_epa.h +++ b/servers/physics_3d/gjk_epa.h @@ -34,7 +34,7 @@ #include "collision_solver_3d_sw.h" #include "shape_3d_sw.h" -bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, real_t p_margin_A = 0.0, real_t p_margin_B = 0.0); -bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B); +bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, real_t p_margin_A = 0.0, real_t p_margin_B = 0.0); +bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B); #endif diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp index e9efddf165..7315e9c709 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp @@ -84,7 +84,7 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { return (y < 0.0f) ? -angle : angle; } -ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &rbAFrame, const Transform &rbBFrame) : +ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) : Joint3DSW(_arr, 2) { A = rbA; B = rbB; @@ -211,7 +211,7 @@ bool ConeTwistJoint3DSW::setup(real_t p_timestep) { // Twist limits if (m_twistSpan >= real_t(0.)) { Vector3 b2Axis22 = B->get_transform().basis.xform(this->m_rbBFrame.basis.get_axis(1)); - Quat rotationArc = Quat(b2Axis1, b1Axis1); + Quaternion rotationArc = Quaternion(b2Axis1, b1Axis1); Vector3 TwistRef = rotationArc.xform(b2Axis22); real_t twist = atan2fast(TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2)); diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h index b871ea50db..608847352c 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h @@ -73,8 +73,8 @@ public: JacobianEntry3DSW m_jac[3]; //3 orthogonal linear constraints real_t m_appliedImpulse; - Transform m_rbAFrame; - Transform m_rbBFrame; + Transform3D m_rbAFrame; + Transform3D m_rbBFrame; real_t m_limitSoftness; real_t m_biasFactor; @@ -107,7 +107,7 @@ public: virtual bool setup(real_t p_step) override; virtual void solve(real_t p_step) override; - ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &rbAFrame, const Transform &rbBFrame); + ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame); void setAngularOnly(bool angularOnly) { m_angularOnly = angularOnly; diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp index 7c504764a7..56aba24b42 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp @@ -219,7 +219,7 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis( //////////////////////////// G6DOFTranslationalLimitMotorSW //////////////////////////////////// -Generic6DOFJoint3DSW::Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA) : +Generic6DOFJoint3DSW::Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA) : Joint3DSW(_arr, 2), m_frameInA(frameInA), m_frameInB(frameInB), diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index 8af76cefc2..d46437e782 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -81,7 +81,7 @@ public: //! temp_variables //!@{ - real_t m_currentLimitError; //! How much is violated this limit + real_t m_currentLimitError; //!< How much is violated this limit int m_currentLimit; //!< 0=free, 1=at lo limit, 2=at hi limit real_t m_accumulatedImpulse; //!@} @@ -113,7 +113,7 @@ public: return (m_enableMotor || m_currentLimit != 0); } - //! calculates error + //! calculates error /*! calculates m_currentLimit and m_currentLimitError. */ @@ -185,8 +185,8 @@ protected: //! relative_frames //!@{ - Transform m_frameInA; //!< the constraint space w.r.t body A - Transform m_frameInB; //!< the constraint space w.r.t body B + Transform3D m_frameInA; //!< the constraint space w.r.t body A + Transform3D m_frameInB; //!< the constraint space w.r.t body B //!@} //! Jacobians @@ -209,8 +209,8 @@ protected: //! temporal variables //!@{ real_t m_timeStep; - Transform m_calculatedTransformA; - Transform m_calculatedTransformB; + Transform3D m_calculatedTransformA; + Transform3D m_calculatedTransformB; Vector3 m_calculatedAxisAngleDiff; Vector3 m_calculatedAxis[3]; @@ -233,7 +233,7 @@ protected: void calculateAngleInfo(); public: - Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA); + Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB, bool useLinearReferenceFrameA); virtual PhysicsServer3D::JointType get_type() const override { return PhysicsServer3D::JOINT_TYPE_6DOF; } @@ -251,7 +251,7 @@ public: /*! \sa Generic6DOFJointSW.getFrameOffsetA, Generic6DOFJointSW.getFrameOffsetB, Generic6DOFJointSW.calculateAngleInfo. */ - const Transform &getCalculatedTransformA() const { + const Transform3D &getCalculatedTransformA() const { return m_calculatedTransformA; } @@ -259,23 +259,23 @@ public: /*! \sa Generic6DOFJointSW.getFrameOffsetA, Generic6DOFJointSW.getFrameOffsetB, Generic6DOFJointSW.calculateAngleInfo. */ - const Transform &getCalculatedTransformB() const { + const Transform3D &getCalculatedTransformB() const { return m_calculatedTransformB; } - const Transform &getFrameOffsetA() const { + const Transform3D &getFrameOffsetA() const { return m_frameInA; } - const Transform &getFrameOffsetB() const { + const Transform3D &getFrameOffsetB() const { return m_frameInB; } - Transform &getFrameOffsetA() { + Transform3D &getFrameOffsetA() { return m_frameInA; } - Transform &getFrameOffsetB() { + Transform3D &getFrameOffsetB() { return m_frameInB; } @@ -327,7 +327,7 @@ public: return &m_angularLimits[index]; } - //! Retrieves the limit informacion + //! Retrieves the limit informacion G6DOFTranslationalLimitMotor3DSW *getTranslationalLimitMotor() { return &m_linearLimits; } diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp index bb8858c28a..b928f18231 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp @@ -67,7 +67,7 @@ static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { } } -HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameA, const Transform &frameB) : +HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameA, const Transform3D &frameB) : Joint3DSW(_arr, 2) { A = rbA; B = rbB; @@ -126,7 +126,7 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivo rbAxisA1.y, rbAxisA2.y, axisInA.y, rbAxisA1.z, rbAxisA2.z, axisInA.z); - Quat rotationArc = Quat(axisInA, axisInB); + Quaternion rotationArc = Quaternion(axisInA, axisInB); Vector3 rbAxisB1 = rotationArc.xform(rbAxisA1); Vector3 rbAxisB2 = axisInB.cross(rbAxisB1); diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h index 2100f5de44..22eb2f4660 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.h +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h @@ -66,8 +66,8 @@ class HingeJoint3DSW : public Joint3DSW { JacobianEntry3DSW m_jac[3]; //3 orthogonal linear constraints JacobianEntry3DSW m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor - Transform m_rbAFrame; // constraint axii. Assumes z is hinge axis. - Transform m_rbBFrame; + Transform3D m_rbAFrame; // constraint axii. Assumes z is hinge axis. + Transform3D m_rbBFrame; real_t m_motorTargetVelocity; real_t m_maxMotorImpulse; @@ -109,7 +109,7 @@ public: void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value); bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const; - HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameA, const Transform &frameB); + HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameA, const Transform3D &frameB); HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB); }; diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/jacobian_entry_3d_sw.h index 2829a5caf7..6afa70c816 100644 --- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h +++ b/servers/physics_3d/joints/jacobian_entry_3d_sw.h @@ -50,7 +50,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#include "core/math/transform.h" +#include "core/math/transform_3d.h" class JacobianEntry3DSW { public: diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp index 8bd1951311..db9bdb2986 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp @@ -111,7 +111,7 @@ void SliderJoint3DSW::initParams() { //----------------------------------------------------------------------------- -SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB) : +SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB) : Joint3DSW(_arr, 2), m_frameInA(frameInA), m_frameInB(frameInB) { diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h index ef5891d0f9..f357bbd67a 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.h +++ b/servers/physics_3d/joints/slider_joint_3d_sw.h @@ -76,8 +76,8 @@ protected: Body3DSW *_arr[2]; }; - Transform m_frameInA; - Transform m_frameInB; + Transform3D m_frameInA; + Transform3D m_frameInB; // linear limits real_t m_lowerLinLimit; @@ -120,8 +120,8 @@ protected: JacobianEntry3DSW m_jacAng[3]; real_t m_timeStep; - Transform m_calculatedTransformA; - Transform m_calculatedTransformB; + Transform3D m_calculatedTransformA; + Transform3D m_calculatedTransformB; Vector3 m_sliderAxis; Vector3 m_realPivotAInW; @@ -152,19 +152,19 @@ protected: public: // constructors - SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB); + SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform3D &frameInA, const Transform3D &frameInB); //SliderJointSW(); // overrides // access const Body3DSW *getRigidBodyA() const { return A; } const Body3DSW *getRigidBodyB() const { return B; } - const Transform &getCalculatedTransformA() const { return m_calculatedTransformA; } - const Transform &getCalculatedTransformB() const { return m_calculatedTransformB; } - const Transform &getFrameOffsetA() const { return m_frameInA; } - const Transform &getFrameOffsetB() const { return m_frameInB; } - Transform &getFrameOffsetA() { return m_frameInA; } - Transform &getFrameOffsetB() { return m_frameInB; } + const Transform3D &getCalculatedTransformA() const { return m_calculatedTransformA; } + const Transform3D &getCalculatedTransformB() const { return m_calculatedTransformB; } + const Transform3D &getFrameOffsetA() const { return m_frameInA; } + const Transform3D &getFrameOffsetB() const { return m_frameInB; } + Transform3D &getFrameOffsetA() { return m_frameInA; } + Transform3D &getFrameOffsetB() { return m_frameInB; } real_t getLowerLinLimit() { return m_lowerLinLimit; } void setLowerLinLimit(real_t lowerLimit) { m_lowerLinLimit = lowerLimit; } real_t getUpperLinLimit() { return m_upperLinLimit; } diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index f3eb1ae48f..7a95a8abc8 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -262,7 +262,7 @@ PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_overrid return area->get_space_override_mode(); } -void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { +void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -283,7 +283,7 @@ void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) area->set_shape(p_shape_idx, shape); } -void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) { +void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -307,9 +307,9 @@ RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { return shape->get_self(); } -Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { +Transform3D PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { Area3DSW *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, Transform()); + ERR_FAIL_COND_V(!area, Transform3D()); return area->get_shape_transform(p_shape_idx); } @@ -368,7 +368,7 @@ void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const area->set_param(p_param, p_value); }; -void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform &p_transform) { +void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform3D &p_transform) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); @@ -385,9 +385,9 @@ Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) con return area->get_param(p_param); }; -Transform PhysicsServer3DSW::area_get_transform(RID p_area) const { +Transform3D PhysicsServer3DSW::area_get_transform(RID p_area) const { Area3DSW *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, Transform()); + ERR_FAIL_COND_V(!area, Transform3D()); return area->get_transform(); }; @@ -487,7 +487,7 @@ PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const { return body->get_mode(); }; -void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { +void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -507,8 +507,7 @@ void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) body->set_shape(p_shape_idx, shape); } - -void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) { +void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -541,9 +540,9 @@ void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo body->set_shape_as_disabled(p_shape_idx, p_disabled); } -Transform PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { +Transform3D PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, Transform()); + ERR_FAIL_COND_V(!body, Transform3D()); return body->get_shape_transform(p_shape_idx); } @@ -657,19 +656,6 @@ real_t PhysicsServer3DSW::body_get_param(RID p_body, BodyParameter p_param) cons return body->get_param(p_param); }; -void PhysicsServer3DSW::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { - Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND(!body); - body->set_kinematic_margin(p_margin); -} - -real_t PhysicsServer3DSW::body_get_kinematic_safe_margin(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, 0); - - return body->get_kinematic_margin(); -} - void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -868,7 +854,7 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { body->set_ray_pickable(p_enable); } -bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { +bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -876,10 +862,10 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, co _update_shapes(); - return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result, p_exclude_raycast_shapes); + return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } -int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { +int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -1010,7 +996,7 @@ Variant PhysicsServer3DSW::soft_body_get_state(RID p_body, BodyState p_state) co return soft_body->get_state(p_state); } -void PhysicsServer3DSW::soft_body_set_transform(RID p_body, const Transform &p_transform) { +void PhysicsServer3DSW::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!soft_body); @@ -1253,7 +1239,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { return pin_joint->get_position_b(); } -void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { +void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND(!body_A); @@ -1378,7 +1364,7 @@ PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) cons return joint->get_type(); } -void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND(!body_A); @@ -1418,7 +1404,7 @@ real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p return slider_joint->get_param(p_param); } -void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND(!body_A); @@ -1458,7 +1444,7 @@ real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJoint return cone_twist_joint->get_param(p_param); } -void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND(!body_A); diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 0b42f1d605..57b6385758 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -130,13 +130,13 @@ public: virtual void area_set_space(RID p_area, RID p_space) override; virtual RID area_get_space(RID p_area) const override; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) override; + virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) override; - virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) override; + virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) override; virtual int area_get_shape_count(RID p_area) const override; virtual RID area_get_shape(RID p_area, int p_shape_idx) const override; - virtual Transform area_get_shape_transform(RID p_area, int p_shape_idx) const override; + virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const override; virtual void area_remove_shape(RID p_area, int p_shape_idx) override; virtual void area_clear_shapes(RID p_area) override; @@ -147,10 +147,10 @@ public: virtual ObjectID area_get_object_instance_id(RID p_area) const override; virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) override; - virtual void area_set_transform(RID p_area, const Transform &p_transform) override; + virtual void area_set_transform(RID p_area, const Transform3D &p_transform) override; virtual Variant area_get_param(RID p_area, AreaParameter p_param) const override; - virtual Transform area_get_transform(RID p_area) const override; + virtual Transform3D area_get_transform(RID p_area) const override; virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; @@ -173,13 +173,13 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode) override; virtual BodyMode body_get_mode(RID p_body) const override; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) override; + virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) override; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override; - virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) override; + virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) override; virtual int body_get_shape_count(RID p_body) const override; virtual RID body_get_shape(RID p_body, int p_shape_idx) const override; - virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const override; + virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const override; virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override; @@ -204,9 +204,6 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) override; virtual real_t body_get_param(RID p_body, BodyParameter p_param) const override; - virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) override; - virtual real_t body_get_kinematic_safe_margin(RID p_body) const override; - virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override; virtual Variant body_get_state(RID p_body, BodyState p_state) const override; @@ -245,8 +242,8 @@ public: virtual void body_set_ray_pickable(RID p_body, bool p_enable) override; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; + virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; + virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override; @@ -273,7 +270,7 @@ public: virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override; virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const override; - virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) override; + virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override; virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override; @@ -323,7 +320,7 @@ public: virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) override; virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; @@ -332,17 +329,17 @@ public: virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override; virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; - virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; //reference frame is A virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; - virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; //reference frame is A virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; - virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) override; //reference frame is A virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override; virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.cpp b/servers/physics_3d/physics_server_3d_wrap_mt.cpp index f73f67a756..0a89c1a9c9 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.cpp +++ b/servers/physics_3d/physics_server_3d_wrap_mt.cpp @@ -56,7 +56,7 @@ void PhysicsServer3DWrapMT::thread_loop() { step_thread_up = true; while (!exit) { // flush commands one by one, until exit is requested - command_queue.wait_and_flush_one(); + command_queue.wait_and_flush(); } command_queue.flush_all(); // flush all diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h index 69d0fcf3ed..bda2e30dd1 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.h +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -142,14 +142,14 @@ public: FUNC2(area_set_space_override_mode, RID, AreaSpaceOverrideMode); FUNC1RC(AreaSpaceOverrideMode, area_get_space_override_mode, RID); - FUNC4(area_add_shape, RID, RID, const Transform &, bool); + FUNC4(area_add_shape, RID, RID, const Transform3D &, bool); FUNC3(area_set_shape, RID, int, RID); - FUNC3(area_set_shape_transform, RID, int, const Transform &); + FUNC3(area_set_shape_transform, RID, int, const Transform3D &); FUNC3(area_set_shape_disabled, RID, int, bool); FUNC1RC(int, area_get_shape_count, RID); FUNC2RC(RID, area_get_shape, RID, int); - FUNC2RC(Transform, area_get_shape_transform, RID, int); + FUNC2RC(Transform3D, area_get_shape_transform, RID, int); FUNC2(area_remove_shape, RID, int); FUNC1(area_clear_shapes, RID); @@ -157,10 +157,10 @@ public: FUNC1RC(ObjectID, area_get_object_instance_id, RID); FUNC3(area_set_param, RID, AreaParameter, const Variant &); - FUNC2(area_set_transform, RID, const Transform &); + FUNC2(area_set_transform, RID, const Transform3D &); FUNC2RC(Variant, area_get_param, RID, AreaParameter); - FUNC1RC(Transform, area_get_transform, RID); + FUNC1RC(Transform3D, area_get_transform, RID); FUNC2(area_set_collision_mask, RID, uint32_t); FUNC2(area_set_collision_layer, RID, uint32_t); @@ -182,12 +182,12 @@ public: FUNC2(body_set_mode, RID, BodyMode); FUNC1RC(BodyMode, body_get_mode, RID); - FUNC4(body_add_shape, RID, RID, const Transform &, bool); + FUNC4(body_add_shape, RID, RID, const Transform3D &, bool); FUNC3(body_set_shape, RID, int, RID); - FUNC3(body_set_shape_transform, RID, int, const Transform &); + FUNC3(body_set_shape_transform, RID, int, const Transform3D &); FUNC1RC(int, body_get_shape_count, RID); - FUNC2RC(Transform, body_get_shape_transform, RID, int); + FUNC2RC(Transform3D, body_get_shape_transform, RID, int); FUNC2RC(RID, body_get_shape, RID, int); FUNC3(body_set_shape_disabled, RID, int, bool); @@ -213,9 +213,6 @@ public: FUNC3(body_set_param, RID, BodyParameter, real_t); FUNC2RC(real_t, body_get_param, RID, BodyParameter); - FUNC2(body_set_kinematic_safe_margin, RID, real_t); - FUNC1RC(real_t, body_get_kinematic_safe_margin, RID); - FUNC3(body_set_state, RID, BodyState, const Variant &); FUNC2RC(Variant, body_get_state, RID, BodyState); @@ -253,12 +250,12 @@ public: FUNC2(body_set_ray_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { + bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); - return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes); + return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } - int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { + int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_3d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } @@ -293,7 +290,7 @@ public: FUNC3(soft_body_set_state, RID, BodyState, const Variant &); FUNC2RC(Variant, soft_body_get_state, RID, BodyState); - FUNC2(soft_body_set_transform, RID, const Transform &); + FUNC2(soft_body_set_transform, RID, const Transform3D &); FUNC2(soft_body_set_simulation_precision, RID, int); FUNC1RC(int, soft_body_get_simulation_precision, RID); @@ -341,7 +338,7 @@ public: FUNC2(pin_joint_set_local_b, RID, const Vector3 &) FUNC1RC(Vector3, pin_joint_get_local_b, RID) - FUNC5(joint_make_hinge, RID, RID, const Transform &, RID, const Transform &) + FUNC5(joint_make_hinge, RID, RID, const Transform3D &, RID, const Transform3D &) FUNC7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &) FUNC3(hinge_joint_set_param, RID, HingeJointParam, real_t) @@ -350,17 +347,17 @@ public: FUNC3(hinge_joint_set_flag, RID, HingeJointFlag, bool) FUNC2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag) - FUNC5(joint_make_slider, RID, RID, const Transform &, RID, const Transform &) + FUNC5(joint_make_slider, RID, RID, const Transform3D &, RID, const Transform3D &) FUNC3(slider_joint_set_param, RID, SliderJointParam, real_t) FUNC2RC(real_t, slider_joint_get_param, RID, SliderJointParam) - FUNC5(joint_make_cone_twist, RID, RID, const Transform &, RID, const Transform &) + FUNC5(joint_make_cone_twist, RID, RID, const Transform3D &, RID, const Transform3D &) FUNC3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t) FUNC2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam) - FUNC5(joint_make_generic_6dof, RID, RID, const Transform &, RID, const Transform &) + FUNC5(joint_make_generic_6dof, RID, RID, const Transform3D &, RID, const Transform3D &) FUNC4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t) FUNC3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam) diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index ca7248993f..2ffab0c923 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -114,7 +114,7 @@ Plane PlaneShape3DSW::get_plane() const { return plane; } -void PlaneShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void PlaneShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // gibberish, a plane is infinity r_min = -1e7; r_max = 1e7; @@ -174,7 +174,7 @@ bool RayShape3DSW::get_slips_on_slope() const { return slips_on_slope; } -void RayShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void RayShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // don't think this will be even used r_min = 0; r_max = 1; @@ -255,7 +255,7 @@ real_t SphereShape3DSW::get_radius() const { return radius; } -void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { real_t d = p_normal.dot(p_transform.origin); // figure out scale at point @@ -317,7 +317,7 @@ SphereShape3DSW::SphereShape3DSW() { /********** BOX *************/ -void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { // no matter the angle, the box is mirrored anyway Vector3 local_normal = p_transform.basis.xform_inv(p_normal); @@ -507,7 +507,7 @@ BoxShape3DSW::BoxShape3DSW() { /********** CAPSULE *************/ -void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { Vector3 n = p_transform.basis.xform_inv(p_normal).normalized(); real_t h = (n.y > 0) ? height : -height; @@ -674,7 +674,7 @@ CapsuleShape3DSW::CapsuleShape3DSW() { /********** CYLINDER *************/ -void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { Vector3 cylinder_axis = p_transform.basis.get_axis(1).normalized(); real_t axis_dot = cylinder_axis.dot(p_normal); @@ -854,7 +854,7 @@ CylinderShape3DSW::CylinderShape3DSW() { /********** CONVEX POLYGON *************/ -void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { int vertex_count = mesh.vertices.size(); if (vertex_count == 0) { return; @@ -1120,7 +1120,7 @@ ConvexPolygonShape3DSW::ConvexPolygonShape3DSW() { /********** FACE POLYGON *************/ -void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { for (int i = 0; i < 3; i++) { Vector3 v = p_transform.xform(vertex[i]); real_t d = p_normal.dot(v); @@ -1250,7 +1250,7 @@ Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const { return rfaces; } -void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { int count = vertices.size(); if (count == 0) { r_min = 0; @@ -1647,7 +1647,7 @@ int HeightMapShape3DSW::get_depth() const { return depth; } -void HeightMapShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { +void HeightMapShape3DSW::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { //not very useful, but not very used either p_transform.xform(get_aabb()).project_range_in_plane(Plane(p_normal, 0), r_min, r_max); } diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h index 4d2b6ffbed..bc8bd3e695 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/shape_3d_sw.h @@ -86,7 +86,7 @@ public: virtual bool is_concave() const { return false; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const = 0; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const = 0; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0; @@ -130,7 +130,7 @@ public: virtual real_t get_area() const { return Math_INF; } virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_PLANE; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } @@ -157,7 +157,7 @@ public: virtual real_t get_area() const { return 0.0; } virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_RAY; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; @@ -185,7 +185,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_SPHERE; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -210,7 +210,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_BOX; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -239,7 +239,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CAPSULE; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -268,7 +268,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CYLINDER; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -293,7 +293,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -371,7 +371,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONCAVE_POLYGON; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -415,7 +415,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_HEIGHTMAP; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; @@ -441,7 +441,7 @@ struct FaceShape3DSW : public Shape3DSW { const Vector3 &get_vertex(int p_idx) const { return vertex[p_idx]; } - void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; Vector3 get_support(const Vector3 &p_normal) const; virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; @@ -462,11 +462,11 @@ struct MotionShape3DSW : public Shape3DSW { virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; } - void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { + void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { Vector3 cast = p_transform.basis.xform(motion); real_t mina, maxa; real_t minb, maxb; - Transform ofsb = p_transform; + Transform3D ofsb = p_transform; ofsb.origin += cast; shape->project_range(p_normal, p_transform, mina, maxa); shape->project_range(p_normal, ofsb, minb, maxb); diff --git a/servers/physics_3d/soft_body_3d_sw.cpp b/servers/physics_3d/soft_body_3d_sw.cpp index f63a470cbe..63a0fe11ba 100644 --- a/servers/physics_3d/soft_body_3d_sw.cpp +++ b/servers/physics_3d/soft_body_3d_sw.cpp @@ -289,7 +289,7 @@ void SoftBody3DSW::update_link_constants() { } } -void SoftBody3DSW::apply_nodes_transform(const Transform &p_transform) { +void SoftBody3DSW::apply_nodes_transform(const Transform3D &p_transform) { if (soft_mesh.is_null()) { return; } @@ -684,7 +684,7 @@ void SoftBody3DSW::generate_bending_constraints(int p_distance) { // // This function takes in a list of interdependent Links and tries // to maximize the distance between calculation -// of dependent links. This increases the amount of parallelism that can +// of dependent links. This increases the amount of parallelism that can // be exploited by out-of-order instruction processors with large but // (inevitably) finite instruction windows. // diff --git a/servers/physics_3d/soft_body_3d_sw.h b/servers/physics_3d/soft_body_3d_sw.h index 98e554218b..ac8bcbf0b9 100644 --- a/servers/physics_3d/soft_body_3d_sw.h +++ b/servers/physics_3d/soft_body_3d_sw.h @@ -201,7 +201,7 @@ private: void reset_link_rest_lengths(); void update_link_constants(); - void apply_nodes_transform(const Transform &p_transform); + void apply_nodes_transform(const Transform3D &p_transform); void add_velocity(const Vector3 &p_velocity); @@ -231,7 +231,7 @@ public: SoftBody3DSW *get_soft_body() const { return soft_body; } virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_SOFT_BODY; } - virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { r_min = r_max = 0.0; } + virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { r_min = r_max = 0.0; } virtual Vector3 get_support(const Vector3 &p_normal) const { return Vector3(); } virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 2df824b320..4392202084 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -59,7 +59,7 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; - //Transform ai = p_xform.affine_inverse(); + //Transform3D ai = p_xform.affine_inverse(); for (int i = 0; i < amount; i++) { if (cc >= p_result_max) { @@ -79,7 +79,7 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + Transform3D inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); inv_xform.affine_invert(); if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point))) { @@ -136,7 +136,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - Transform inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); + Transform3D inv_xform = col_obj->get_shape_inv_transform(shape_idx) * col_obj->get_inv_transform(); Vector3 local_from = inv_xform.xform(begin); Vector3 local_to = inv_xform.xform(end); @@ -146,7 +146,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec Vector3 shape_point, shape_normal; if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) { - Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + Transform3D xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); shape_point = xform.xform(shape_point); real_t ld = normal.dot(shape_point); @@ -180,7 +180,7 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec return true; } -int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return 0; } @@ -194,7 +194,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans int cc = 0; - //Transform ai = p_xform.affine_inverse(); + //Transform3D ai = p_xform.affine_inverse(); for (int i = 0; i < amount; i++) { if (cc >= p_result_max) { @@ -239,7 +239,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans return cc; } -bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { +bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -252,7 +252,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor real_t best_safe = 1; real_t best_unsafe = 1; - Transform xform_inv = p_xform.affine_inverse(); + Transform3D xform_inv = p_xform.affine_inverse(); MotionShape3DSW mshape; mshape.shape = shape; mshape.motion = xform_inv.basis.xform(p_motion); @@ -280,7 +280,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor Vector3 point_A, point_B; Vector3 sep_axis = p_motion.normalized(); - Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) { continue; @@ -348,7 +348,7 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor return true; } -bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { if (p_result_max <= 0) { return false; } @@ -432,7 +432,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, int p_index_A, const Vect rd->best_local_shape = rd->local_shape; } -bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { +bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -512,7 +512,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob continue; } - Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i); + Transform3D shape_xform = obj->get_transform() * obj->get_shape_transform(i); Shape3DSW *shape = obj->get_shape(i); Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point)); @@ -573,7 +573,7 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { return amount; } -int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) { +int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) { AABB body_aabb; bool shapes_found = false; @@ -598,7 +598,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra body_aabb = p_transform.xform(p_body->get_inv_transform().xform(body_aabb)); body_aabb = body_aabb.grow(p_margin); - Transform body_transform = p_transform; + Transform3D body_transform = p_transform; for (int i = 0; i < p_result_max; i++) { //reset results @@ -636,7 +636,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra continue; } - Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); + Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { const CollisionObject3DSW *col_obj = intersection_query_results[i]; @@ -724,7 +724,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra return rays_found; } -bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) { +bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) { //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -768,7 +768,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons real_t motion_length = p_motion.length(); Vector3 motion_normal = p_motion / motion_length; - Transform body_transform = p_from; + Transform3D body_transform = p_from; bool recovered = false; @@ -797,7 +797,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons continue; } - Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); + Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j); Shape3DSW *body_shape = p_body->get_shape(j); if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) { continue; @@ -868,14 +868,14 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons continue; } - Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); + Transform3D body_shape_xform = body_transform * p_body->get_shape_transform(j); Shape3DSW *body_shape = p_body->get_shape(j); if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) { continue; } - Transform body_shape_xform_inv = body_shape_xform.affine_inverse(); + Transform3D body_shape_xform_inv = body_shape_xform.affine_inverse(); MotionShape3DSW mshape; mshape.shape = body_shape; mshape.motion = body_shape_xform_inv.basis.xform(p_motion); @@ -893,7 +893,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons Vector3 point_A, point_B; Vector3 sep_axis = motion_normal; - Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); + Transform3D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) { continue; @@ -960,7 +960,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } //it collided, let's get the rest info in unsafe advance - Transform ugt = body_transform; + Transform3D ugt = body_transform; ugt.origin += p_motion * unsafe; _RestCallbackData rcd; @@ -979,7 +979,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons continue; } - Transform body_shape_xform = ugt * p_body->get_shape_transform(j); + Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j); Shape3DSW *body_shape = p_body->get_shape(j); if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) { diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h index 3a8f452e54..18e93c90cc 100644 --- a/servers/physics_3d/space_3d_sw.h +++ b/servers/physics_3d/space_3d_sw.h @@ -50,10 +50,10 @@ public: virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override; + virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; + virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override; PhysicsDirectSpaceState3DSW(); @@ -203,8 +203,8 @@ public: void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; } uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; } - int test_body_ray_separation(Body3DSW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin); - bool test_body_motion(Body3DSW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes); + int test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin); + bool test_body_motion(Body3DSW *p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes); Space3DSW(); ~Space3DSW(); diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 7c5761cc61..faab4f43b8 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -509,12 +509,6 @@ void PhysicsTestMotionResult2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape"); } -PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() { - colliding = false; - - result.collider_shape = 0; -} - /////////////////////////////////////// bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { @@ -715,8 +709,8 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(BODY_MODE_STATIC); BIND_ENUM_CONSTANT(BODY_MODE_KINEMATIC); - BIND_ENUM_CONSTANT(BODY_MODE_RIGID); - BIND_ENUM_CONSTANT(BODY_MODE_CHARACTER); + BIND_ENUM_CONSTANT(BODY_MODE_DYNAMIC); + BIND_ENUM_CONSTANT(BODY_MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(BODY_PARAM_BOUNCE); BIND_ENUM_CONSTANT(BODY_PARAM_FRICTION); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index f2836961f2..35430e4a46 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -164,8 +164,8 @@ public: Vector2 normal; RID rid; ObjectID collider_id; - Object *collider; - int shape; + Object *collider = nullptr; + int shape = 0; Variant metadata; }; @@ -174,8 +174,8 @@ public: struct ShapeResult { RID rid; ObjectID collider_id; - Object *collider; - int shape; + Object *collider = nullptr; + int shape = 0; Variant metadata; }; @@ -193,7 +193,7 @@ public: Vector2 normal; RID rid; ObjectID collider_id; - int shape; + int shape = 0; Vector2 linear_velocity; //velocity at contact point Variant metadata; }; @@ -370,8 +370,8 @@ public: enum BodyMode { BODY_MODE_STATIC, BODY_MODE_KINEMATIC, - BODY_MODE_RIGID, - BODY_MODE_CHARACTER + BODY_MODE_DYNAMIC, + BODY_MODE_DYNAMIC_LOCKED, }; virtual RID body_create() = 0; @@ -493,17 +493,11 @@ public: Vector2 collision_point; Vector2 collision_normal; Vector2 collider_velocity; - int collision_local_shape; + int collision_local_shape = 0; ObjectID collider_id; RID collider; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; - - MotionResult() { - collision_local_shape = 0; - collider_shape = 0; - collider_id = ObjectID(); - } }; virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; @@ -607,7 +601,6 @@ class PhysicsTestMotionResult2D : public Reference { GDCLASS(PhysicsTestMotionResult2D, Reference); PhysicsServer2D::MotionResult result; - bool colliding; friend class PhysicsServer2D; protected: @@ -616,7 +609,6 @@ protected: public: PhysicsServer2D::MotionResult *get_result_ptr() const { return const_cast<PhysicsServer2D::MotionResult *>(&result); } - //bool is_colliding() const; Vector2 get_motion() const; Vector2 get_motion_remainder() const; @@ -627,8 +619,6 @@ public: RID get_collider_rid() const; Object *get_collider() const; int get_collider_shape() const; - - PhysicsTestMotionResult2D(); }; typedef PhysicsServer2D *(*CreatePhysicsServer2DCallback)(); diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 80a9bd4c0b..1634169e8a 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -128,7 +128,7 @@ void PhysicsDirectBodyState3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleep_state", "is_sleeping"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform"), "set_transform", "get_transform"); } PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {} @@ -156,11 +156,11 @@ RID PhysicsShapeQueryParameters3D::get_shape_rid() const { return shape; } -void PhysicsShapeQueryParameters3D::set_transform(const Transform &p_transform) { +void PhysicsShapeQueryParameters3D::set_transform(const Transform3D &p_transform) { transform = p_transform; } -Transform PhysicsShapeQueryParameters3D::get_transform() const { +Transform3D PhysicsShapeQueryParameters3D::get_transform() const { return transform; } @@ -242,7 +242,7 @@ void PhysicsShapeQueryParameters3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::RID, "shape_rid"), "set_shape_rid", "get_shape_rid"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform"), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled"); } @@ -458,7 +458,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_space_override_mode", "area", "mode"), &PhysicsServer3D::area_set_space_override_mode); ClassDB::bind_method(D_METHOD("area_get_space_override_mode", "area"), &PhysicsServer3D::area_get_space_override_mode); - ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform", "disabled"), &PhysicsServer3D::area_add_shape, DEFVAL(Transform()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform", "disabled"), &PhysicsServer3D::area_add_shape, DEFVAL(Transform3D()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &PhysicsServer3D::area_set_shape); ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &PhysicsServer3D::area_set_shape_transform); ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disabled"), &PhysicsServer3D::area_set_shape_disabled); @@ -502,7 +502,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &PhysicsServer3D::body_set_collision_mask); ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &PhysicsServer3D::body_get_collision_mask); - ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform", "disabled"), &PhysicsServer3D::body_add_shape, DEFVAL(Transform()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform", "disabled"), &PhysicsServer3D::body_add_shape, DEFVAL(Transform3D()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("body_set_shape", "body", "shape_idx", "shape"), &PhysicsServer3D::body_set_shape); ClassDB::bind_method(D_METHOD("body_set_shape_transform", "body", "shape_idx", "transform"), &PhysicsServer3D::body_set_shape_transform); ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disabled"), &PhysicsServer3D::body_set_shape_disabled); @@ -523,9 +523,6 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_param", "body", "param", "value"), &PhysicsServer3D::body_set_param); ClassDB::bind_method(D_METHOD("body_get_param", "body", "param"), &PhysicsServer3D::body_get_param); - ClassDB::bind_method(D_METHOD("body_set_kinematic_safe_margin", "body", "margin"), &PhysicsServer3D::body_set_kinematic_safe_margin); - ClassDB::bind_method(D_METHOD("body_get_kinematic_safe_margin", "body"), &PhysicsServer3D::body_get_kinematic_safe_margin); - ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &PhysicsServer3D::body_set_state); ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &PhysicsServer3D::body_get_state); @@ -717,8 +714,8 @@ void PhysicsServer3D::_bind_methods() { BIND_ENUM_CONSTANT(BODY_MODE_STATIC); BIND_ENUM_CONSTANT(BODY_MODE_KINEMATIC); - BIND_ENUM_CONSTANT(BODY_MODE_RIGID); - BIND_ENUM_CONSTANT(BODY_MODE_CHARACTER); + BIND_ENUM_CONSTANT(BODY_MODE_DYNAMIC); + BIND_ENUM_CONSTANT(BODY_MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(BODY_PARAM_BOUNCE); BIND_ENUM_CONSTANT(BODY_PARAM_FRICTION); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index c434109865..ec4914641a 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -59,8 +59,8 @@ public: virtual void set_angular_velocity(const Vector3 &p_velocity) = 0; virtual Vector3 get_angular_velocity() const = 0; - virtual void set_transform(const Transform &p_transform) = 0; - virtual Transform get_transform() const = 0; + virtual void set_transform(const Transform3D &p_transform) = 0; + virtual Transform3D get_transform() const = 0; virtual void add_central_force(const Vector3 &p_force) = 0; virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0; @@ -102,7 +102,7 @@ class PhysicsShapeQueryParameters3D : public Reference { RES shape_ref; RID shape; - Transform transform; + Transform3D transform; real_t margin; Set<RID> exclude; uint32_t collision_mask; @@ -119,8 +119,8 @@ public: void set_shape_rid(const RID &p_shape); RID get_shape_rid() const; - void set_transform(const Transform &p_transform); - Transform get_transform() const; + void set_transform(const Transform3D &p_transform); + Transform3D get_transform() const; void set_margin(real_t p_margin); real_t get_margin() const; @@ -157,8 +157,8 @@ public: struct ShapeResult { RID rid; ObjectID collider_id; - Object *collider; - int shape; + Object *collider = nullptr; + int shape = 0; }; virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; @@ -168,28 +168,28 @@ public: Vector3 normal; RID rid; ObjectID collider_id; - Object *collider; - int shape; + Object *collider = nullptr; + int shape = 0; }; virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) = 0; - virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual int intersect_shape(const RID &p_shape, const Transform3D &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; struct ShapeRestInfo { Vector3 point; Vector3 normal; RID rid; ObjectID collider_id; - int shape; + int shape = 0; Vector3 linear_velocity; //velocity at contact point }; - virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; + virtual bool cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0; - virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool collide_shape(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; - virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; + virtual bool rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0; @@ -335,13 +335,13 @@ public: virtual void area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) = 0; virtual AreaSpaceOverrideMode area_get_space_override_mode(RID p_area) const = 0; - virtual void area_add_shape(RID p_area, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) = 0; + virtual void area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) = 0; virtual void area_set_shape(RID p_area, int p_shape_idx, RID p_shape) = 0; - virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) = 0; + virtual void area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) = 0; virtual int area_get_shape_count(RID p_area) const = 0; virtual RID area_get_shape(RID p_area, int p_shape_idx) const = 0; - virtual Transform area_get_shape_transform(RID p_area, int p_shape_idx) const = 0; + virtual Transform3D area_get_shape_transform(RID p_area, int p_shape_idx) const = 0; virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0; virtual void area_clear_shapes(RID p_area) = 0; @@ -352,10 +352,10 @@ public: virtual ObjectID area_get_object_instance_id(RID p_area) const = 0; virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) = 0; - virtual void area_set_transform(RID p_area, const Transform &p_transform) = 0; + virtual void area_set_transform(RID p_area, const Transform3D &p_transform) = 0; virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const = 0; - virtual Transform area_get_transform(RID p_area) const = 0; + virtual Transform3D area_get_transform(RID p_area) const = 0; virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0; @@ -374,8 +374,8 @@ public: enum BodyMode { BODY_MODE_STATIC, BODY_MODE_KINEMATIC, - BODY_MODE_RIGID, - BODY_MODE_CHARACTER + BODY_MODE_DYNAMIC, + BODY_MODE_DYNAMIC_LOCKED, }; virtual RID body_create() = 0; @@ -386,13 +386,13 @@ public: virtual void body_set_mode(RID p_body, BodyMode p_mode) = 0; virtual BodyMode body_get_mode(RID p_body) const = 0; - virtual void body_add_shape(RID p_body, RID p_shape, const Transform &p_transform = Transform(), bool p_disabled = false) = 0; + virtual void body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform = Transform3D(), bool p_disabled = false) = 0; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) = 0; - virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) = 0; + virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) = 0; virtual int body_get_shape_count(RID p_body) const = 0; virtual RID body_get_shape(RID p_body, int p_shape_idx) const = 0; - virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const = 0; + virtual Transform3D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0; virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0; virtual void body_clear_shapes(RID p_body) = 0; @@ -428,9 +428,6 @@ public: virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) = 0; virtual real_t body_get_param(RID p_body, BodyParameter p_param) const = 0; - virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0; - virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0; - //state enum BodyState { BODY_STATE_TRANSFORM, @@ -500,19 +497,14 @@ public: Vector3 collision_point; Vector3 collision_normal; Vector3 collider_velocity; - int collision_local_shape; + int collision_local_shape = 0; ObjectID collider_id; RID collider; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; - MotionResult() { - collision_local_shape = 0; - collider_id = ObjectID(); - collider_shape = 0; - } }; - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; + virtual bool body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { real_t collision_depth; @@ -526,7 +518,7 @@ public: Variant collider_metadata; }; - virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0; + virtual int body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0; /* SOFT BODY */ @@ -554,7 +546,7 @@ public: virtual void soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) = 0; virtual Variant soft_body_get_state(RID p_body, BodyState p_state) const = 0; - virtual void soft_body_set_transform(RID p_body, const Transform &p_transform) = 0; + virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) = 0; virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) = 0; @@ -642,7 +634,7 @@ public: HINGE_JOINT_FLAG_MAX }; - virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) = 0; virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) = 0; @@ -679,7 +671,7 @@ public: }; - virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) = 0; //reference frame is A virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) = 0; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0; @@ -693,7 +685,7 @@ public: CONE_TWIST_MAX }; - virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) = 0; //reference frame is A virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) = 0; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0; @@ -734,7 +726,7 @@ public: G6DOF_JOINT_FLAG_MAX }; - virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) = 0; //reference frame is A virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) = 0; virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const = 0; diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index bfc7e7684f..96c9137c6e 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -45,7 +45,7 @@ public: void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} + void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} @@ -59,7 +59,7 @@ public: void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} - void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) override {} + void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} @@ -145,9 +145,9 @@ public: void directional_shadow_quality_set(RS::ShadowQuality p_quality) override {} RID light_instance_create(RID p_light) override { return RID(); } - void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) override {} + void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {} void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {} - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} + void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} void light_instance_mark_visible(RID p_light_instance) override {} RID reflection_atlas_create() override { return RID(); } @@ -155,7 +155,7 @@ public: void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {} RID reflection_probe_instance_create(RID p_probe) override { return RID(); } - void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) override {} + void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override {} void reflection_probe_release_atlas_index(RID p_instance) override {} bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; } bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; } @@ -163,21 +163,21 @@ public: bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; } RID decal_instance_create(RID p_decal) override { return RID(); } - void decal_instance_set_transform(RID p_decal, const Transform &p_transform) override {} + void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {} RID lightmap_instance_create(RID p_lightmap) override { return RID(); } - void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) override {} + void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {} - RID gi_probe_instance_create(RID p_gi_probe) override { return RID(); } - void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) override {} - bool gi_probe_needs_update(RID p_probe) const override { return false; } - void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} + RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); } + void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {} + bool voxel_gi_needs_update(RID p_probe) const override { return false; } + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} - void gi_probe_set_quality(RS::GIProbeQuality) override {} + void voxel_gi_set_quality(RS::VoxelGIQuality) override {} - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {} - void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} - void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} + void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {} + void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} void set_time(double p_time, double p_step) override {} @@ -347,7 +347,7 @@ public: int multimesh_get_instance_count(RID p_multimesh) const override { return 0; } void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {} - void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) override {} + void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) override {} void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override {} void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override {} void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override {} @@ -355,7 +355,7 @@ public: RID multimesh_get_mesh(RID p_multimesh) const override { return RID(); } AABB multimesh_get_aabb(RID p_multimesh) const override { return AABB(); } - Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const override { return Transform(); } + Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const override { return Transform3D(); } Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override { return Transform2D(); } Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override { return Color(); } Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override { return Color(); } @@ -389,8 +389,8 @@ public: void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {} void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override {} int skeleton_get_bone_count(RID p_skeleton) const override { return 0; } - void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) override {} - Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override { return Transform(); } + void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override {} + Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override { return Transform3D(); } void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override {} Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override { return Transform2D(); } @@ -482,52 +482,52 @@ public: AABB decal_get_aabb(RID p_decal) const override { return AABB(); } - /* GI PROBE API */ + /* VOXEL GI API */ - RID gi_probe_allocate() override { return RID(); } - void gi_probe_initialize(RID p_rid) override {} - void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} + RID voxel_gi_allocate() override { return RID(); } + void voxel_gi_initialize(RID p_rid) override {} + void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} - AABB gi_probe_get_bounds(RID p_gi_probe) const override { return AABB(); } - Vector3i gi_probe_get_octree_size(RID p_gi_probe) const override { return Vector3i(); } - Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const override { return Vector<uint8_t>(); } - Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const override { return Vector<uint8_t>(); } - Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const override { return Vector<uint8_t>(); } + AABB voxel_gi_get_bounds(RID p_voxel_gi) const override { return AABB(); } + Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override { return Vector3i(); } + Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); } + Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); } + Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override { return Vector<uint8_t>(); } - Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const override { return Vector<int>(); } - Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const override { return Transform(); } + Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override { return Vector<int>(); } + Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override { return Transform3D(); } - void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) override {} - float gi_probe_get_dynamic_range(RID p_gi_probe) const override { return 0; } + void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override {} + float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override { return 0; } - void gi_probe_set_propagation(RID p_gi_probe, float p_range) override {} - float gi_probe_get_propagation(RID p_gi_probe) const override { return 0; } + void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override {} + float voxel_gi_get_propagation(RID p_voxel_gi) const override { return 0; } - void gi_probe_set_energy(RID p_gi_probe, float p_range) override {} - float gi_probe_get_energy(RID p_gi_probe) const override { return 0.0; } + void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override {} + float voxel_gi_get_energy(RID p_voxel_gi) const override { return 0.0; } - void gi_probe_set_ao(RID p_gi_probe, float p_ao) override {} - float gi_probe_get_ao(RID p_gi_probe) const override { return 0; } + void voxel_gi_set_ao(RID p_voxel_gi, float p_ao) override {} + float voxel_gi_get_ao(RID p_voxel_gi) const override { return 0; } - void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) override {} - float gi_probe_get_ao_size(RID p_gi_probe) const override { return 0; } + void voxel_gi_set_ao_size(RID p_voxel_gi, float p_strength) override {} + float voxel_gi_get_ao_size(RID p_voxel_gi) const override { return 0; } - void gi_probe_set_bias(RID p_gi_probe, float p_range) override {} - float gi_probe_get_bias(RID p_gi_probe) const override { return 0.0; } + void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override {} + float voxel_gi_get_bias(RID p_voxel_gi) const override { return 0.0; } - void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) override {} - float gi_probe_get_normal_bias(RID p_gi_probe) const override { return 0.0; } + void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override {} + float voxel_gi_get_normal_bias(RID p_voxel_gi) const override { return 0.0; } - void gi_probe_set_interior(RID p_gi_probe, bool p_enable) override {} - bool gi_probe_is_interior(RID p_gi_probe) const override { return false; } + void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override {} + bool voxel_gi_is_interior(RID p_voxel_gi) const override { return false; } - void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) override {} - bool gi_probe_is_using_two_bounces(RID p_gi_probe) const override { return false; } + void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override {} + bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override { return false; } - void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) override {} - float gi_probe_get_anisotropy_strength(RID p_gi_probe) const override { return 0; } + void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override {} + float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override { return 0; } - uint32_t gi_probe_get_version(RID p_gi_probe) override { return 0; } + uint32_t voxel_gi_get_version(RID p_voxel_gi) override { return 0; } /* LIGHTMAP CAPTURE */ RID lightmap_allocate() override { return RID(); } @@ -555,7 +555,7 @@ public: RID particles_allocate() override { return RID(); } void particles_initialize(RID p_rid) override {} void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override {} - void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {} + void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {} void particles_set_emitting(RID p_particles, bool p_emitting) override {} void particles_set_amount(RID p_particles, int p_amount) override {} void particles_set_lifetime(RID p_particles, float p_lifetime) override {} @@ -577,7 +577,7 @@ public: void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) override {} void particles_set_trails(RID p_particles, bool p_enable, float p_length) override {} - void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses) override {} + void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) override {} void particles_restart(RID p_particles) override {} @@ -590,7 +590,7 @@ public: AABB particles_get_current_aabb(RID p_particles) override { return AABB(); } AABB particles_get_aabb(RID p_particles) const override { return AABB(); } - void particles_set_emission_transform(RID p_particles, const Transform &p_transform) override {} + void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) override {} bool particles_get_emitting(RID p_particles) override { return false; } int particles_get_draw_passes(RID p_particles) const override { return 0; } @@ -622,7 +622,7 @@ public: RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); } RID particles_collision_instance_create(RID p_collision) override { return RID(); }; - void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) override{}; + void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override{}; void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override{}; /* GLOBAL VARIABLES */ diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 67003a6f64..6e126ea77e 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -44,10 +44,10 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *)); for (int i = 0; i < p_child_item_count; i++) { - _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); + _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true); } if (p_canvas_item) { - _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr); + _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true); } RendererCanvasRender::Item *list = nullptr; @@ -104,98 +104,7 @@ void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<Rende } while (ysort_owner && ysort_owner->sort_y); } -void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) { - Item *ci = p_canvas_item; - - if (!ci->visible) { - return; - } - - if (ci->children_order_dirty) { - ci->child_items.sort_custom<ItemIndexSort>(); - ci->children_order_dirty = false; - } - - Rect2 rect = ci->get_rect(); - Transform2D xform = ci->xform; - if (snapping_2d_transforms_to_pixel) { - xform.elements[2] = xform.elements[2].floor(); - } - xform = p_transform * xform; - - Rect2 global_rect = xform.xform(rect); - global_rect.position += p_clip_rect.position; - - if (ci->use_parent_material && p_material_owner) { - ci->material_owner = p_material_owner; - } else { - p_material_owner = ci; - ci->material_owner = nullptr; - } - - Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a); - - if (modulate.a < 0.007) { - return; - } - - int child_item_count = ci->child_items.size(); - Item **child_items = ci->child_items.ptrw(); - - if (ci->clip) { - if (p_canvas_clip != nullptr) { - ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect); - } else { - ci->final_clip_rect = global_rect; - } - ci->final_clip_rect.position = ci->final_clip_rect.position.round(); - ci->final_clip_rect.size = ci->final_clip_rect.size.round(); - ci->final_clip_owner = ci; - - } else { - ci->final_clip_owner = p_canvas_clip; - } - - if (ci->sort_y) { - if (ci->ysort_children_count == -1) { - ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count); - } - - child_item_count = ci->ysort_children_count; - child_items = (Item **)alloca(child_item_count * sizeof(Item *)); - - int i = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i); - - SortArray<Item *, ItemPtrSort> sorter; - sorter.sort(child_items, child_item_count); - } - - if (ci->z_relative) { - p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); - } else { - p_z = ci->z_index; - } - - RendererCanvasRender::Item *canvas_group_from = nullptr; - bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr); - if (use_canvas_group) { - int zidx = p_z - RS::CANVAS_ITEM_Z_MIN; - canvas_group_from = z_last_list[zidx]; - } - - for (int i = 0; i < child_item_count; i++) { - if ((!child_items[i]->behind && !use_canvas_group) || (ci->sort_y && child_items[i]->sort_y)) { - continue; - } - if (ci->sort_y) { - _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); - } else { - _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); - } - } - +void _attach_canvas_item_for_draw(RendererCanvasCull::Item *ci, RendererCanvasCull::Item *p_canvas_clip, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, const Transform2D &xform, const Rect2 &p_clip_rect, Rect2 global_rect, const Color &modulate, int p_z, RendererCanvasCull::Item *p_material_owner, bool use_canvas_group, RendererCanvasRender::Item *canvas_group_from) { if (ci->copy_back_buffer) { ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).intersection(p_clip_rect); } @@ -229,7 +138,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 // We have two choices now, if user has drawn something, we must assume users wants to draw the "mask", so compute the size based on this. // If nothing has been drawn, we just take it over and draw it ourselves. if (ci->canvas_group->fit_empty && (ci->commands == nullptr || - (ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) { + (ci->commands->next == nullptr && ci->commands->type == RendererCanvasCull::Item::Command::TYPE_RECT && (static_cast<RendererCanvasCull::Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) { // No commands, or sole command is the one used to draw, so we (re)create the draw command. ci->clear(); @@ -291,15 +200,117 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 ci->next = nullptr; } +} - for (int i = 0; i < child_item_count; i++) { - if (child_items[i]->behind || use_canvas_group || (ci->sort_y && child_items[i]->sort_y)) { - continue; +void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort) { + Item *ci = p_canvas_item; + + if (!ci->visible) { + return; + } + + if (ci->children_order_dirty) { + ci->child_items.sort_custom<ItemIndexSort>(); + ci->children_order_dirty = false; + } + + Rect2 rect = ci->get_rect(); + Transform2D xform = ci->xform; + if (snapping_2d_transforms_to_pixel) { + xform.elements[2] = xform.elements[2].floor(); + } + xform = p_transform * xform; + + Rect2 global_rect = xform.xform(rect); + global_rect.position += p_clip_rect.position; + + if (ci->use_parent_material && p_material_owner) { + ci->material_owner = p_material_owner; + } else { + p_material_owner = ci; + ci->material_owner = nullptr; + } + + Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a); + + if (modulate.a < 0.007) { + return; + } + + int child_item_count = ci->child_items.size(); + Item **child_items = ci->child_items.ptrw(); + + if (ci->clip) { + if (p_canvas_clip != nullptr) { + ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect); + } else { + ci->final_clip_rect = global_rect; } - if (ci->sort_y) { - _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); + ci->final_clip_rect.position = ci->final_clip_rect.position.round(); + ci->final_clip_rect.size = ci->final_clip_rect.size.round(); + ci->final_clip_owner = ci; + + } else { + ci->final_clip_owner = p_canvas_clip; + } + + if (ci->z_relative) { + p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); + } else { + p_z = ci->z_index; + } + + if (ci->sort_y) { + if (allow_y_sort) { + if (ci->ysort_children_count == -1) { + ci->ysort_children_count = 0; + _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count); + } + + child_item_count = ci->ysort_children_count + 1; + child_items = (Item **)alloca(child_item_count * sizeof(Item *)); + + child_items[0] = ci; + int i = 1; + _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i); + ci->ysort_xform = ci->xform.affine_inverse(); + + SortArray<Item *, ItemPtrSort> sorter; + sorter.sort(child_items, child_item_count); + + for (i = 0; i < child_item_count; i++) { + _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false); + } } else { - _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); + RendererCanvasRender::Item *canvas_group_from = nullptr; + bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr); + if (use_canvas_group) { + int zidx = p_z - RS::CANVAS_ITEM_Z_MIN; + canvas_group_from = z_last_list[zidx]; + } + + _attach_canvas_item_for_draw(ci, p_canvas_clip, z_list, z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from); + } + } else { + RendererCanvasRender::Item *canvas_group_from = nullptr; + bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr); + if (use_canvas_group) { + int zidx = p_z - RS::CANVAS_ITEM_Z_MIN; + canvas_group_from = z_last_list[zidx]; + } + + for (int i = 0; i < child_item_count; i++) { + if (!child_items[i]->behind && !use_canvas_group) { + continue; + } + _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true); + } + _attach_canvas_item_for_draw(ci, p_canvas_clip, z_list, z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from); + for (int i = 0; i < child_item_count; i++) { + if (child_items[i]->behind || use_canvas_group) { + continue; + } + _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true); } } } diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index b71f8e5a9a..37391d7c0e 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -158,7 +158,7 @@ public: private: void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); - void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner); + void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort); RendererCanvasRender::Item **z_list; RendererCanvasRender::Item **z_last_list; diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 2669a73014..b952ecbff0 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -374,7 +374,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID } } -void ClusterBuilderRD::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) { +void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) { view_xform = p_view_transform.affine_inverse(); projection = p_cam_projection; z_near = projection.get_z_near(); diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index dc1707b534..ebb81abdad 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -167,7 +167,7 @@ private: uint32_t render_element_count = 0; uint32_t render_element_max = 0; - Transform view_xform; + Transform3D view_xform; CameraMatrix adjusted_projection; CameraMatrix projection; float z_far = 0; @@ -220,9 +220,9 @@ private: public: void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer); - void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y); + void begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y); - _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) { + _FORCE_INLINE_ void add_light(LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) { if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) { return; //max number elements reached } @@ -232,7 +232,7 @@ public: RenderElementData &e = render_elements[render_element_count]; - Transform xform = view_xform * p_transform; + Transform3D xform = view_xform * p_transform; float radius = xform.basis.get_uniform_scale(); if (radius > 0.98 || radius < 1.02) { @@ -317,7 +317,7 @@ public: render_element_count++; } - _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform &p_transform, const Vector3 &p_half_extents) { + _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform3D &p_transform, const Vector3 &p_half_extents) { if (p_box_type == BOX_TYPE_DECAL && cluster_count_by_type[ELEMENT_TYPE_DECAL] == max_elements_by_type) { return; //max number elements reached } @@ -326,7 +326,7 @@ public: } RenderElementData &e = render_elements[render_element_count]; - Transform xform = view_xform * p_transform; + Transform3D xform = view_xform * p_transform; //extract scale and scale the matrix by it, makes things simpler Vector3 scale = p_half_extents; diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 563e08fdcb..872f7b5beb 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1401,19 +1401,19 @@ void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_ RD::get_singleton()->draw_list_draw(draw_list, true); } -void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { +void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { ResolvePushConstant push_constant; push_constant.screen_size[0] = p_screen_size.x; push_constant.screen_size[1] = p_screen_size.y; push_constant.samples = p_samples; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_giprobe.is_valid() ? RESOLVE_MODE_GI_GIPROBE : RESOLVE_MODE_GI]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_source_depth, p_source_normal_roughness), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_dest_depth, p_dest_normal_roughness), 1); - if (p_source_giprobe.is_valid()) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_giprobe), 2); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_giprobe), 3); + if (p_source_voxel_gi.is_valid()) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_voxel_gi), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_voxel_gi), 3); } RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); @@ -1907,7 +1907,7 @@ EffectsRD::EffectsRD() { { Vector<String> resolve_modes; resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n"); - resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define GIPROBE_RESOLVE\n"); + resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n"); resolve.shader.initialize(resolve_modes); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 1ba25e301b..ab0100f8f9 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -585,7 +585,7 @@ class EffectsRD { enum ResolveMode { RESOLVE_MODE_GI, - RESOLVE_MODE_GI_GIPROBE, + RESOLVE_MODE_GI_VOXEL_GI, RESOLVE_MODE_MAX }; @@ -750,7 +750,7 @@ public: void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); - void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void sort_buffer(RID p_uniform_set, int p_size); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 16c6273ff6..e1c2836f6c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -93,8 +93,8 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() } } -void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_giprobe() { - if (!giprobe_buffer.is_valid()) { +void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() { + if (!voxelgi_buffer.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8_UINT; tf.width = width; @@ -105,41 +105,41 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_giprobe() RD::TextureFormat tf_aa = tf; tf_aa.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; tf_aa.samples = texture_samples; - giprobe_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView()); + voxelgi_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView()); } else { tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; } tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; - giprobe_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + voxelgi_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); Vector<RID> fb; if (msaa != RS::VIEWPORT_MSAA_DISABLED) { fb.push_back(depth_msaa); fb.push_back(normal_roughness_buffer_msaa); - fb.push_back(giprobe_buffer_msaa); + fb.push_back(voxelgi_buffer_msaa); } else { fb.push_back(depth); fb.push_back(normal_roughness_buffer); - fb.push_back(giprobe_buffer); + fb.push_back(voxelgi_buffer); } - depth_normal_roughness_giprobe_fb = RD::get_singleton()->framebuffer_create(fb); + depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb); } } void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { - if (giprobe_buffer != RID()) { - RD::get_singleton()->free(giprobe_buffer); - giprobe_buffer = RID(); + if (voxelgi_buffer != RID()) { + RD::get_singleton()->free(voxelgi_buffer); + voxelgi_buffer = RID(); - if (giprobe_buffer_msaa.is_valid()) { - RD::get_singleton()->free(giprobe_buffer_msaa); - giprobe_buffer_msaa = RID(); + if (voxelgi_buffer_msaa.is_valid()) { + RD::get_singleton()->free(voxelgi_buffer_msaa); + voxelgi_buffer_msaa = RID(); } - depth_normal_roughness_giprobe_fb = RID(); + depth_normal_roughness_voxelgi_fb = RID(); } if (color_msaa.is_valid()) { @@ -398,8 +398,8 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS; } break; - case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: { - shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE; + case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { + shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI; } break; case PASS_MODE_DEPTH_MATERIAL: { shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL; @@ -498,8 +498,8 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); } break; - case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: { - _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); + case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { + _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); } break; case PASS_MODE_DEPTH_MATERIAL: { _render_list_template<PASS_MODE_DEPTH_MATERIAL>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); @@ -817,7 +817,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u if (inst->store_transform_cache) { RendererStorageRD::store_transform(inst->transform, instance_data.transform); } else { - RendererStorageRD::store_transform(Transform(), instance_data.transform); + RendererStorageRD::store_transform(Transform3D(), instance_data.transform); } instance_data.flags = inst->flags_cache; @@ -948,14 +948,14 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS; } - if (inst->gi_probes[0].is_valid()) { + if (inst->voxel_gi_instances[0].is_valid()) { uint32_t probe0_index = 0xFFFF; uint32_t probe1_index = 0xFFFF; - for (uint32_t j = 0; j < scene_state.giprobes_used; j++) { - if (scene_state.giprobe_ids[j] == inst->gi_probes[0]) { + for (uint32_t j = 0; j < scene_state.voxelgis_used; j++) { + if (scene_state.voxelgi_ids[j] == inst->voxel_gi_instances[0]) { probe0_index = j; - } else if (scene_state.giprobe_ids[j] == inst->gi_probes[1]) { + } else if (scene_state.voxelgi_ids[j] == inst->voxel_gi_instances[1]) { probe1_index = j; } } @@ -966,7 +966,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con } inst->gi_offset_cache = probe0_index | (probe1_index << 16); - flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; + flags |= INSTANCE_DATA_FLAG_USE_VOXEL_GI; uses_gi = true; } else { if (p_using_sdfgi && inst->can_sdfgi) { @@ -1061,14 +1061,14 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con } } -void RenderForwardClustered::_setup_giprobes(const PagedArray<RID> &p_giprobes) { - scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES)); - for (uint32_t i = 0; i < scene_state.giprobes_used; i++) { - scene_state.giprobe_ids[i] = p_giprobes[i]; +void RenderForwardClustered::_setup_voxelgis(const PagedArray<RID> &p_voxelgis) { + scene_state.voxelgis_used = MIN(p_voxelgis.size(), uint32_t(MAX_VOXEL_GI_INSTANCESS)); + for (uint32_t i = 0; i < scene_state.voxelgis_used; i++) { + scene_state.voxelgi_ids[i] = p_voxelgis[i]; } } -void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) { +void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) { scene_state.lightmaps_used = 0; for (int i = 0; i < (int)p_lightmaps.size(); i++) { if (i >= (int)scene_state.max_lightmaps) { @@ -1120,7 +1120,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool using_separate_specular = false; bool using_ssr = false; bool using_sdfgi = false; - bool using_giprobe = false; + bool using_voxelgi = false; bool reverse_cull = false; if (render_buffer) { @@ -1129,19 +1129,19 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co opaque_framebuffer = render_buffer->color_fb; - if (p_render_data->gi_probes->size() > 0) { - using_giprobe = true; + if (p_render_data->voxel_gi_instances->size() > 0) { + using_voxelgi = true; } - if (!p_render_data->environment.is_valid() && using_giprobe) { - depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE; + if (!p_render_data->environment.is_valid() && using_voxelgi) { + depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI; - } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_giprobe)) { + } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { if (environment_is_sdfgi_enabled(p_render_data->environment)) { - depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe + depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi using_sdfgi = true; } else { - depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; + depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } if (environment_is_ssr_enabled(p_render_data->environment)) { @@ -1164,10 +1164,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co depth_framebuffer = render_buffer->depth_normal_roughness_fb; depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0)); } break; - case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: { + case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { _allocate_normal_roughness_texture(render_buffer); - render_buffer->ensure_giprobe(); - depth_framebuffer = render_buffer->depth_normal_roughness_giprobe_fb; + render_buffer->ensure_voxelgi(); + depth_framebuffer = render_buffer->depth_normal_roughness_voxelgi_fb; depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0)); depth_pass_clear.push_back(Color(0, 0, 0, 0)); } break; @@ -1198,12 +1198,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Render Setup"); _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform); - _setup_giprobes(*p_render_data->gi_probes); + _setup_voxelgis(*p_render_data->voxel_gi_instances); _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_giprobe); + _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_depth(); _fill_instance_data(RENDER_LIST_OPAQUE); @@ -1293,7 +1293,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color = p_default_bg_color; } - bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION; + bool debug_voxelgis = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION; bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; bool depth_pre_pass = depth_framebuffer.is_valid(); @@ -1301,7 +1301,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool continue_depth = false; if (depth_pre_pass) { //depth pre pass - bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_giprobe); + bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi); if (needs_pre_resolve) { RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); } else { @@ -1312,32 +1312,32 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear); RD::get_singleton()->draw_list_end(); //start compute processes here, so they run at the same time as depth pre-pass - _post_prepass_render(p_render_data, using_sdfgi || using_giprobe); + _post_prepass_render(p_render_data, using_sdfgi || using_voxelgi); } RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass"); RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); - bool finish_depth = using_ssao || using_sdfgi || using_giprobe; + bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); if (needs_pre_resolve) { - _pre_resolve_render(p_render_data, using_sdfgi || using_giprobe); + _pre_resolve_render(p_render_data, using_sdfgi || using_voxelgi); } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { RENDER_TIMESTAMP("Resolve Depth Pre-Pass"); RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass"); - if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) { + if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) { if (needs_pre_resolve) { RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); } static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; - storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_giprobe ? render_buffer->giprobe_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_giprobe ? render_buffer->giprobe_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]); + storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]); } else if (finish_depth) { RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); } @@ -1347,7 +1347,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co continue_depth = !finish_depth; } - _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID()); + _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID()); RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); @@ -1363,8 +1363,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; { - bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_giprobes || debug_sdfgi_probes); - bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_giprobes || debug_sdfgi_probes); + bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes); + bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes); //regular forward for now Vector<Color> c; @@ -1389,8 +1389,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_end_label(); - if (debug_giprobes) { - //debug giprobes + if (debug_voxelgis) { + //debug voxelgis bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); @@ -1398,16 +1398,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co dc.set_depth_correction(true); CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); - RD::get_singleton()->draw_command_begin_label("Debug GIProbes"); - for (int i = 0; i < (int)p_render_data->gi_probes->size(); i++) { - gi.debug_giprobe((*p_render_data->gi_probes)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); + RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs"); + for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) { + gi.debug_voxel_gi((*p_render_data->voxel_gi_instances)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, 1.0); } RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_list_end(); } if (debug_sdfgi_probes) { - //debug giprobes + //debug voxelgis bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); @@ -1498,7 +1498,8 @@ void RenderForwardClustered::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { + +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1585,7 +1586,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup Render Collider Heightfield"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1622,7 +1623,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering Material"); RD::get_singleton()->draw_command_begin_label("Render Material"); @@ -1796,7 +1797,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i render_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size); //print_line("pass: " + itos(i) + " cam hsize: " + rtos(h_size) + " vsize: " + rtos(v_size) + " dsize " + rtos(d_size)); - Transform to_bounds; + Transform3D to_bounds; to_bounds.origin = p_bounds.position; to_bounds.basis.scale(p_bounds.size); @@ -2058,11 +2059,11 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_GI_PROBES); + u.ids.resize(MAX_VOXEL_GI_INSTANCESS); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); - for (int i = 0; i < MAX_GI_PROBES; i++) { - if (p_render_data && i < (int)p_render_data->gi_probes->size()) { - RID tex = gi.gi_probe_instance_get_texture((*p_render_data->gi_probes)[i]); + for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { + if (p_render_data && i < (int)p_render_data->voxel_gi_instances->size()) { + RID tex = gi.voxel_gi_instance_get_texture((*p_render_data->voxel_gi_instances)[i]); if (!tex.is_valid()) { tex = default_tex; } @@ -2169,7 +2170,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_data->render_buffers) : render_buffers_get_default_gi_probe_buffer()); + u.ids.push_back(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer()); uniforms.push_back(u); } { @@ -2278,13 +2279,13 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te } { - // No GIProbes + // No VoxelGIs RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_GI_PROBES); + u.ids.resize(MAX_VOXEL_GI_INSTANCESS); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); - for (int i = 0; i < MAX_GI_PROBES; i++) { + for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { u.ids.write[i] = default_tex; } @@ -2632,7 +2633,7 @@ void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geome ginstance->can_sdfgi = false; if (!lightmap_instance_is_valid(ginstance->lightmap_instance)) { - if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) { + if (ginstance->voxel_gi_instances[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) { ginstance->can_sdfgi = true; } } @@ -2719,7 +2720,7 @@ void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstanc ginstance->mesh_instance = p_mesh_instance; _geometry_instance_mark_dirty(ginstance); } -void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { +void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); ginstance->transform = p_transform; @@ -2815,7 +2816,7 @@ void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry } uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() { - return (1 << RS::INSTANCE_GI_PROBE); + return (1 << RS::INSTANCE_VOXEL_GI); } void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { } @@ -2824,30 +2825,31 @@ void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(G void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { } -Transform RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) { +Transform3D RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform()); + ERR_FAIL_COND_V(!ginstance, Transform3D()); return ginstance->transform; } + AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); ERR_FAIL_COND_V(!ginstance, AABB()); return ginstance->data->aabb; } -void RenderForwardClustered::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) { +void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - if (p_gi_probe_instance_count > 0) { - ginstance->gi_probes[0] = p_gi_probe_instances[0]; + if (p_voxel_gi_instance_count > 0) { + ginstance->voxel_gi_instances[0] = p_voxel_gi_instances[0]; } else { - ginstance->gi_probes[0] = RID(); + ginstance->voxel_gi_instances[0] = RID(); } - if (p_gi_probe_instance_count > 1) { - ginstance->gi_probes[1] = p_gi_probe_instances[1]; + if (p_voxel_gi_instance_count > 1) { + ginstance->voxel_gi_instances[1] = p_voxel_gi_instances[1]; } else { - ginstance->gi_probes[1] = RID(); + ginstance->voxel_gi_instances[1] = RID(); } } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index bed3c3b219..e276e55de2 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -52,9 +52,9 @@ class RenderForwardClustered : public RendererSceneRenderRD { enum { SDFGI_MAX_CASCADES = 8, - MAX_GI_PROBES = 8, + MAX_VOXEL_GI_INSTANCESS = 8, MAX_LIGHTMAPS = 8, - MAX_GI_PROBES_PER_INSTANCE = 2, + MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE = 2, INSTANCE_DATA_BUFFER_MIN_SIZE = 4096 }; @@ -79,7 +79,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID depth; RID specular; RID normal_roughness_buffer; - RID giprobe_buffer; + RID voxelgi_buffer; RS::ViewportMSAA msaa; RD::TextureSamples texture_samples; @@ -89,11 +89,11 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID specular_msaa; RID normal_roughness_buffer_msaa; RID roughness_buffer_msaa; - RID giprobe_buffer_msaa; + RID voxelgi_buffer_msaa; RID depth_fb; RID depth_normal_roughness_fb; - RID depth_normal_roughness_giprobe_fb; + RID depth_normal_roughness_voxelgi_fb; RID color_fb; RID color_specular_fb; RID specular_only_fb; @@ -101,7 +101,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID render_sdfgi_uniform_set; void ensure_specular(); - void ensure_giprobe(); + void ensure_voxelgi(); void clear(); virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa); @@ -132,7 +132,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { PASS_MODE_SHADOW_DP, PASS_MODE_DEPTH, PASS_MODE_DEPTH_NORMAL_ROUGHNESS, - PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, + PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI, PASS_MODE_DEPTH_MATERIAL, PASS_MODE_SDF, }; @@ -189,7 +189,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, - INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11, + INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -318,8 +318,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t max_lightmap_captures; RID lightmap_capture_buffer; - RID giprobe_ids[MAX_GI_PROBES]; - uint32_t giprobes_used = 0; + RID voxelgi_ids[MAX_VOXEL_GI_INSTANCESS]; + uint32_t voxelgis_used = 0; bool used_screen_texture = false; bool used_normal_texture = false; @@ -350,8 +350,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { static RenderForwardClustered *singleton; void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); - void _setup_giprobes(const PagedArray<RID> &p_giprobes); - void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); + void _setup_voxelgis(const PagedArray<RID> &p_voxelgis); + void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform); struct RenderElementInfo { uint32_t repeat : 22; @@ -458,8 +458,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { bool can_sdfgi = false; //used during setup uint32_t base_flags = 0; - Transform transform; - RID gi_probes[MAX_GI_PROBES_PER_INSTANCE]; + Transform3D transform; + RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE]; RID lightmap_instance; GeometryInstanceLightmapSH *lightmap_sh = nullptr; GeometryInstanceSurfaceDataCache *surface_caches = nullptr; @@ -569,14 +569,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color); virtual void _render_shadow_begin(); - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); virtual void _render_shadow_process(); virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); - virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); + virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances); + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances); public: virtual GeometryInstance *geometry_instance_create(RID p_base); @@ -584,7 +584,7 @@ public: virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override); virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials); virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance); - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb); + virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb); virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask); virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias); virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable); @@ -594,7 +594,7 @@ public: virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset); virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable); - virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance); + virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance); virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance); virtual void geometry_instance_free(GeometryInstance *p_geometry_instance); @@ -603,7 +603,7 @@ public: virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count); virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count); virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count); - virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count); + virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count); virtual bool free(RID p_rid); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 5a26b5abbb..dcfdf14784 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -311,7 +311,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { //none, leave empty } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { blend_state = blend_state_depth_normal_roughness; - } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) { + } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) { blend_state = blend_state_depth_normal_roughness_giprobe; } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) { blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way @@ -563,7 +563,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); - shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_GIPROBE\n"); + shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); shader_versions.push_back(""); @@ -721,7 +721,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; } - actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 7c8879686b..6845133825 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -48,7 +48,7 @@ public: SHADER_VERSION_DEPTH_PASS, SHADER_VERSION_DEPTH_PASS_DP, SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS, - SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE, + SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI, SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL, SHADER_VERSION_DEPTH_PASS_WITH_SDF, SHADER_VERSION_COLOR_PASS, diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 4e93fa5333..370d8eca4e 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -226,11 +226,11 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_GI_PROBES); + u.ids.resize(MAX_VOXEL_GI_INSTANCESS); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); - for (int i = 0; i < MAX_GI_PROBES; i++) { - if (i < (int)p_gi_probes.size()) { - RID tex = gi.gi_probe_instance_get_texture(p_gi_probes[i]); + for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { + if (i < (int)p_voxel_gi_instances.size()) { + RID tex = gi.voxel_gi_instance_get_texture(p_voxel_gi_instances[i]); if (!tex.is_valid()) { tex = default_tex; } @@ -283,7 +283,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ return render_pass_uniform_sets[p_index]; } -void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) { +void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) { // This probably needs to change... scene_state.lightmaps_used = 0; for (int i = 0; i < (int)p_lightmaps.size(); i++) { @@ -547,7 +547,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -634,7 +634,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ -void RenderForwardMobile::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering Material"); RD::get_singleton()->draw_command_begin_label("Render Material"); @@ -746,7 +746,7 @@ void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_ // we don't do GI in low end.. } -void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup Render Collider Heightfield"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1364,7 +1364,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr if (inst->store_transform_cache) { RendererStorageRD::store_transform(inst->transform, push_constant.transform); } else { - RendererStorageRD::store_transform(Transform(), push_constant.transform); + RendererStorageRD::store_transform(Transform3D(), push_constant.transform); } push_constant.flags = inst->flags_cache; @@ -1557,7 +1557,7 @@ void RenderForwardMobile::geometry_instance_set_mesh_instance(GeometryInstance * _geometry_instance_mark_dirty(ginstance); } -void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { +void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); ginstance->transform = p_transform; @@ -1645,9 +1645,9 @@ void RenderForwardMobile::geometry_instance_set_cast_double_sided_shadows(Geomet _geometry_instance_mark_dirty(ginstance); } -Transform RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) { +Transform3D RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform()); + ERR_FAIL_COND_V(!ginstance, Transform3D()); return ginstance->transform; } @@ -1725,7 +1725,7 @@ void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstanc } } -void RenderForwardMobile::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) { +void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { // We do not have this here! } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index bf911319f2..a2189693d0 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -104,7 +104,7 @@ protected: PASS_MODE_SHADOW_DP, // PASS_MODE_DEPTH, // PASS_MODE_DEPTH_NORMAL_ROUGHNESS, - // PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, + // PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI, PASS_MODE_DEPTH_MATERIAL, // PASS_MODE_SDF, }; @@ -152,14 +152,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color); virtual void _render_shadow_begin(); - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); virtual void _render_shadow_process(); virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); - virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); + virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances); + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances); uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -174,7 +174,7 @@ protected: static RenderForwardMobile *singleton; void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); - void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); + void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform); RID render_base_uniform_set; LocalVector<RID> render_pass_uniform_sets; @@ -390,7 +390,7 @@ protected: INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, - INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11, + INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -489,7 +489,7 @@ protected: RID transforms_uniform_set; float depth = 0; bool mirror = false; - Transform transform; + Transform3D transform; bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform bool non_uniform_scale = false; AABB transformed_aabb; //needed for LOD @@ -568,7 +568,7 @@ public: virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override); virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials); virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance); - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb); + virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb); virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask); virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias); virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable); @@ -578,7 +578,7 @@ public: virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset); virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable); - virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance); + virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance); virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance); virtual void geometry_instance_free(GeometryInstance *p_geometry_instance); @@ -587,7 +587,7 @@ public: virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count); virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count); virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count); - virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count); + virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count); virtual bool free(RID p_rid); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 883273c8a5..0d9dfbc51b 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -342,7 +342,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { //none, leave empty } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { blend_state = blend_state_depth_normal_roughness; - } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) { + } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) { blend_state = blend_state_depth_normal_roughness_giprobe; } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) { blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way @@ -737,7 +737,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; } - actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 70c1705bff..9d325fe69b 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -76,7 +76,7 @@ void RendererCanvasRenderRD::_update_transform_2d_to_mat2x3(const Transform2D &p p_mat2x3[5] = p_transform.elements[2][1]; } -void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) { +void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4) { p_mat4[0] = p_transform.basis.elements[0][0]; p_mat4[1] = p_transform.basis.elements[1][0]; p_mat4[2] = p_transform.basis.elements[2][0]; @@ -1250,7 +1250,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p Size2i ssize = storage->render_target_get_size(p_to_render_target); - Transform screen_transform; + Transform3D screen_transform; screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); @@ -1539,7 +1539,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, } Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); - projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); + projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1617,7 +1617,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh CameraMatrix projection; projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance); - projection = projection * CameraMatrix(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); + projection = projection * CameraMatrix(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 890a4e3649..8c1376e2dc 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -433,7 +433,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { _FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3); _FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4); - _FORCE_INLINE_ void _update_transform_to_mat4(const Transform &p_transform, float *p_mat4); + _FORCE_INLINE_ void _update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4); void _update_shadow_atlas(); diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index b289b17fad..43a4058ab6 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -1099,7 +1099,7 @@ void RendererSceneGIRD::SDFGI::update_cascades() { RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) { +void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) { if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) { Vector<RD::Uniform> uniforms; { @@ -1367,7 +1367,7 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr } } -void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { +void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { /* Update general SDFGI Buffer */ SDFGIData sdfgi_data; @@ -2012,10 +2012,10 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 } //////////////////////////////////////////////////////////////////////////////// -// GIProbeInstance +// VoxelGIInstance -void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { - uint32_t data_version = storage->gi_probe_get_data_version(probe); +void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { + uint32_t data_version = storage->voxel_gi_get_data_version(probe); // (RE)CREATE IF NEEDED @@ -2034,11 +2034,11 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c dynamic_maps.clear(); - Vector3i octree_size = storage->gi_probe_get_octree_size(probe); + Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); if (octree_size != Vector3i()) { //can create a 3D texture - Vector<int> levels = storage->gi_probe_get_level_counts(probe); + Vector<int> levels = storage->voxel_gi_get_level_counts(probe); RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; @@ -2064,7 +2064,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c } for (int i = 0; i < levels.size(); i++) { - GIProbeInstance::Mipmap mipmap; + VoxelGIInstance::Mipmap mipmap; mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, RD::TEXTURE_SLICE_3D); mipmap.level = levels.size() - i - 1; mipmap.cell_offset = 0; @@ -2078,14 +2078,14 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->gi_probe_get_octree_buffer(probe)); + u.ids.push_back(storage->voxel_gi_get_octree_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(storage->gi_probe_get_data_buffer(probe)); + u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } @@ -2100,7 +2100,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->gi_probe_get_sdf_texture(probe)); + u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2118,11 +2118,11 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->gi_probe_lights_uniform); + u.ids.push_back(gi->voxel_gi_lights_uniform); copy_uniforms.push_back(u); } - mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT], 0); + mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT], 0); copy_uniforms = uniforms; //restore @@ -2133,9 +2133,9 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c u.ids.push_back(texture); copy_uniforms.push_back(u); } - mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0); + mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0); } else { - mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP], 0); + mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP], 0); } } @@ -2147,7 +2147,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c uniforms.push_back(u); } - mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE], 0); + mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE], 0); mipmaps.push_back(mipmap); } @@ -2158,7 +2158,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c int mipmap_index = 0; while (mipmap_index < mipmaps.size()) { - GIProbeInstance::DynamicMap dmap; + VoxelGIInstance::DynamicMap dmap; if (oversample > 0) { dmap.size = dynamic_map_size * (1 << oversample); @@ -2217,7 +2217,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->gi_probe_lights_uniform); + u.ids.push_back(gi->voxel_gi_lights_uniform); uniforms.push_back(u); } @@ -2253,7 +2253,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->gi_probe_get_sdf_texture(probe)); + u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2278,7 +2278,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c uniforms.push_back(u); } - dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0); + dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0); } } else { bool plot = dmap.mipmap >= 0; @@ -2322,7 +2322,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->gi_probe_get_sdf_texture(probe)); + u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { @@ -2345,7 +2345,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c dmap.uniform_set = RD::get_singleton()->uniform_set_create( uniforms, - gi->giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)], + gi->voxel_gi_lighting_shader_version_shaders[(write && plot) ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)], 0); } @@ -2370,15 +2370,15 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c uint32_t light_count = 0; if (p_update_light_instances || p_dynamic_objects.size() > 0) { - light_count = MIN(gi->gi_probe_max_lights, (uint32_t)p_light_instances.size()); + light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size()); { - Transform to_cell = storage->gi_probe_get_to_cell_xform(probe); - Transform to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse(); + Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(probe); + Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse(); //update lights for (uint32_t i = 0; i < light_count; i++) { - GIProbeLight &l = gi->gi_probe_lights[i]; + VoxelGILight &l = gi->voxel_gi_lights[i]; RID light_instance = p_light_instances[i]; RID light = p_scene_render->light_instance_get_base_light(light_instance); @@ -2399,7 +2399,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); - Transform xform = p_scene_render->light_instance_get_base_transform(light_instance); + Transform3D xform = p_scene_render->light_instance_get_base_transform(light_instance); Vector3 pos = to_probe_xform.xform(xform.origin); Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_axis(2)).normalized(); @@ -2415,7 +2415,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c l.has_shadow = storage->light_has_shadow(light); } - RD::get_singleton()->buffer_update(gi->gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi->gi_probe_lights); + RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights); } } @@ -2424,17 +2424,17 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c if (mipmaps.size()) { //can update mipmaps - Vector3i probe_size = storage->gi_probe_get_octree_size(probe); + Vector3i probe_size = storage->voxel_gi_get_octree_size(probe); - GIProbePushConstant push_constant; + VoxelGIPushConstant push_constant; push_constant.limits[0] = probe_size.x; push_constant.limits[1] = probe_size.y; push_constant.limits[2] = probe_size.z; push_constant.stack_size = mipmaps.size(); push_constant.emission_scale = 1.0; - push_constant.propagation = storage->gi_probe_get_propagation(probe); - push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe); + push_constant.propagation = storage->voxel_gi_get_propagation(probe); + push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); push_constant.light_count = light_count; push_constant.aniso_strength = 0; @@ -2446,7 +2446,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c int passes; if (p_update_light_instances) { - passes = storage->gi_probe_is_using_two_bounces(probe) ? 2 : 1; + passes = storage->voxel_gi_is_using_two_bounces(probe) ? 2 : 1; } else { passes = 1; //only re-blitting is necessary } @@ -2457,9 +2457,9 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c if (p_update_light_instances) { for (int i = 0; i < mipmaps.size(); i++) { if (i == 0) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[pass == 0 ? VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT : VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]); } else if (i == 1) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP]); } if (pass == 1 || i > 0) { @@ -2477,7 +2477,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; while (wg_todo) { int wg_count = MIN(wg_todo, wg_limit_x); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); wg_todo -= wg_count; push_constant.cell_offset += wg_count * wg_size; @@ -2487,7 +2487,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done } - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE]); for (int i = 0; i < mipmaps.size(); i++) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0); @@ -2498,7 +2498,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; while (wg_todo) { int wg_count = MIN(wg_todo, wg_limit_x); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant)); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); wg_todo -= wg_count; push_constant.cell_offset += wg_count * wg_size; @@ -2513,15 +2513,15 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c has_dynamic_object_data = false; //clear until dynamic object data is used again if (p_dynamic_objects.size() && dynamic_maps.size()) { - Vector3i octree_size = storage->gi_probe_get_octree_size(probe); + Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z); - Transform oversample_scale; + Transform3D oversample_scale; oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier)); - Transform to_cell = oversample_scale * storage->gi_probe_get_to_cell_xform(probe); - Transform to_world_xform = transform * to_cell.affine_inverse(); - Transform to_probe_xform = to_world_xform.affine_inverse(); + Transform3D to_cell = oversample_scale * storage->voxel_gi_get_to_cell_xform(probe); + Transform3D to_world_xform = transform * to_cell.affine_inverse(); + Transform3D to_probe_xform = to_world_xform.affine_inverse(); AABB probe_aabb(Vector3(), octree_size); @@ -2529,7 +2529,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i]; - //transform aabb to giprobe + //transform aabb to voxel_gi AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance)); //this needs to wrap to grid resolution to avoid jitter @@ -2576,7 +2576,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c Vector3 up_dir = render_up[j]; Vector3 center = aabb.position + aabb.size * 0.5; - Transform xform; + Transform3D xform; xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir); Vector3 x_dir = xform.basis.get_axis(0).abs(); @@ -2601,8 +2601,8 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size)); - GIProbeDynamicPushConstant push_constant; - memset(&push_constant, 0, sizeof(GIProbeDynamicPushConstant)); + VoxelGIDynamicPushConstant push_constant; + memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant)); push_constant.limits[0] = octree_size.x; push_constant.limits[1] = octree_size.y; push_constant.limits[2] = octree_size.z; @@ -2619,7 +2619,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c push_constant.z_base = xform.origin[z_axis]; push_constant.z_sign = (z_flip ? -1.0 : 1.0); push_constant.pos_multiplier = float(1.0) / multiplier; - push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe); + push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); push_constant.flip_x = x_flip; push_constant.flip_y = y_flip; push_constant.rect_pos[0] = rect.position[0]; @@ -2631,16 +2631,16 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c push_constant.prev_rect_size[0] = 0; push_constant.prev_rect_size[1] = 0; push_constant.on_mipmap = false; - push_constant.propagation = storage->gi_probe_get_propagation(probe); + push_constant.propagation = storage->voxel_gi_get_propagation(probe); push_constant.pad[0] = 0; push_constant.pad[1] = 0; push_constant.pad[2] = 0; //process lighting RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant)); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1); //print_line("rect: " + itos(i) + ": " + rect); @@ -2695,14 +2695,14 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c RD::get_singleton()->compute_list_add_barrier(compute_list); if (dynamic_maps[k].mipmap < 0) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]); } else if (k < dynamic_maps.size() - 1) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]); } else { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]); } RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant)); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1); } @@ -2713,22 +2713,22 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c has_dynamic_object_data = true; //clear until dynamic object data is used again } - last_probe_version = storage->gi_probe_get_version(probe); + last_probe_version = storage->voxel_gi_get_version(probe); } -void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { if (mipmaps.size() == 0) { return; } - CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->gi_probe_get_to_cell_xform(probe).affine_inverse()); + CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->voxel_gi_get_to_cell_xform(probe).affine_inverse()); int level = 0; - Vector3i octree_size = storage->gi_probe_get_octree_size(probe); + Vector3i octree_size = storage->voxel_gi_get_octree_size(probe); - GIProbeDebugPushConstant push_constant; + VoxelGIDebugPushConstant push_constant; push_constant.alpha = p_alpha; - push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe); + push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe); push_constant.cell_offset = mipmaps[level].cell_offset; push_constant.level = level; @@ -2743,15 +2743,15 @@ void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p } } - if (gi->giprobe_debug_uniform_set.is_valid()) { - RD::get_singleton()->free(gi->giprobe_debug_uniform_set); + if (gi->voxel_gi_debug_uniform_set.is_valid()) { + RD::get_singleton()->free(gi->voxel_gi_debug_uniform_set); } Vector<RD::Uniform> uniforms; { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->gi_probe_get_data_buffer(probe)); + u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } { @@ -2776,19 +2776,19 @@ void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p cell_count = mipmaps[level].cell_count; } - gi->giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_debug_shader_version_shaders[0], 0); + gi->voxel_gi_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_debug_shader_version_shaders[0], 0); - int giprobe_debug_pipeline = GI_PROBE_DEBUG_COLOR; + int voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_COLOR; if (p_emission) { - giprobe_debug_pipeline = GI_PROBE_DEBUG_EMISSION; + voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_EMISSION; } else if (p_lighting) { - giprobe_debug_pipeline = has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT; + voxel_gi_debug_pipeline = has_dynamic_object_data ? VOXEL_GI_DEBUG_LIGHT_FULL : VOXEL_GI_DEBUG_LIGHT; } RD::get_singleton()->draw_list_bind_render_pipeline( p_draw_list, - gi->giprobe_debug_shader_version_pipelines[giprobe_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->giprobe_debug_uniform_set, 0); - RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant)); + gi->voxel_gi_debug_shader_version_pipelines[voxel_gi_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->voxel_gi_debug_uniform_set, 0); + RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(VoxelGIDebugPushConstant)); RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36); } @@ -2812,13 +2812,13 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p { //kinda complicated to compute the amount of slots, we try to use as many as we can - gi_probe_max_lights = 32; + voxel_gi_max_lights = 32; - gi_probe_lights = memnew_arr(GIProbeLight, gi_probe_max_lights); - gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight)); - gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality")), 0, 1)); + voxel_gi_lights = memnew_arr(VoxelGILight, voxel_gi_max_lights); + voxel_gi_lights_uniform = RD::get_singleton()->uniform_buffer_create(voxel_gi_max_lights * sizeof(VoxelGILight)); + voxel_gi_quality = RS::VoxelGIQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality")), 0, 1)); - String defines = "\n#define MAX_LIGHTS " + itos(gi_probe_max_lights) + "\n"; + String defines = "\n#define MAX_LIGHTS " + itos(voxel_gi_max_lights) + "\n"; Vector<String> versions; versions.push_back("\n#define MODE_COMPUTE_LIGHT\n"); @@ -2830,11 +2830,11 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n"); versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n"); - giprobe_shader.initialize(versions, defines); - giprobe_lighting_shader_version = giprobe_shader.version_create(); - for (int i = 0; i < GI_PROBE_SHADER_VERSION_MAX; i++) { - giprobe_lighting_shader_version_shaders[i] = giprobe_shader.version_get_shader(giprobe_lighting_shader_version, i); - giprobe_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(giprobe_lighting_shader_version_shaders[i]); + voxel_gi_shader.initialize(versions, defines); + voxel_gi_lighting_shader_version = voxel_gi_shader.version_create(); + for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) { + voxel_gi_lighting_shader_version_shaders[i] = voxel_gi_shader.version_get_shader(voxel_gi_lighting_shader_version, i); + voxel_gi_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(voxel_gi_lighting_shader_version_shaders[i]); } } @@ -2846,10 +2846,10 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p versions.push_back("\n#define MODE_DEBUG_EMISSION\n"); versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n"); - giprobe_debug_shader.initialize(versions, defines); - giprobe_debug_shader_version = giprobe_debug_shader.version_create(); - for (int i = 0; i < GI_PROBE_DEBUG_MAX; i++) { - giprobe_debug_shader_version_shaders[i] = giprobe_debug_shader.version_get_shader(giprobe_debug_shader_version, i); + voxel_gi_debug_shader.initialize(versions, defines); + voxel_gi_debug_shader_version = voxel_gi_debug_shader.version_create(); + for (int i = 0; i < VOXEL_GI_DEBUG_MAX; i++) { + voxel_gi_debug_shader_version_shaders[i] = voxel_gi_debug_shader.version_get_shader(voxel_gi_debug_shader_version, i); RD::PipelineRasterizationState rs; rs.cull_mode = RD::POLYGON_CULL_FRONT; @@ -2858,7 +2858,7 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p ds.enable_depth_write = true; ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; - giprobe_debug_shader_version_pipelines[i].setup(giprobe_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); + voxel_gi_debug_shader_version_pipelines[i].setup(voxel_gi_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); } } @@ -2944,12 +2944,12 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p //calculate tables String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; Vector<String> gi_modes; - gi_modes.push_back("\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); gi_modes.push_back("\n#define USE_SDFGI\n"); - gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n"); - gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n"); gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); - gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n"); + gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); shader.initialize(gi_modes, defines); shader_version = shader.version_create(); @@ -2991,17 +2991,17 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p } } } - default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * MAX_GIPROBES); + default_voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(VoxelGIData) * MAX_VOXEL_GI_INSTANCES); half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); } void RendererSceneGIRD::free() { - RD::get_singleton()->free(default_giprobe_buffer); - RD::get_singleton()->free(gi_probe_lights_uniform); + RD::get_singleton()->free(default_voxel_gi_buffer); + RD::get_singleton()->free(voxel_gi_lights_uniform); RD::get_singleton()->free(sdfgi_ubo); - giprobe_debug_shader.version_free(giprobe_debug_shader_version); - giprobe_shader.version_free(giprobe_lighting_shader_version); + voxel_gi_debug_shader.version_free(voxel_gi_debug_shader_version); + voxel_gi_shader.version_free(voxel_gi_lighting_shader_version); shader.version_free(shader_version); sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader); sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader); @@ -3009,7 +3009,7 @@ void RendererSceneGIRD::free() { sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader); sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader); - memdelete_arr(gi_probe_lights); + memdelete_arr(voxel_gi_lights); } RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { @@ -3020,36 +3020,36 @@ RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironme return sdfgi; } -void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render) { - r_gi_probes_used = 0; +void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { + r_voxel_gi_instances_used = 0; // feels a little dirty to use our container this way but.... RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); - RID gi_probe_buffer = p_scene_render->render_buffers_get_gi_probe_buffer(p_render_buffers); + RID voxel_gi_buffer = p_scene_render->render_buffers_get_voxel_gi_buffer(p_render_buffers); - RD::get_singleton()->draw_command_begin_label("GIProbes Setup"); + RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup"); - GIProbeData gi_probe_data[MAX_GIPROBES]; + VoxelGIData voxel_gi_data[MAX_VOXEL_GI_INSTANCES]; - bool giprobes_changed = false; + bool voxel_gi_instances_changed = false; - Transform to_camera; + Transform3D to_camera; to_camera.origin = p_transform.origin; //only translation, make local - for (int i = 0; i < MAX_GIPROBES; i++) { + for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { RID texture; - if (i < (int)p_gi_probes.size()) { - GIProbeInstance *gipi = get_probe_instance(p_gi_probes[i]); + if (i < (int)p_voxel_gi_instances.size()) { + VoxelGIInstance *gipi = get_probe_instance(p_voxel_gi_instances[i]); if (gipi) { texture = gipi->texture; - GIProbeData &gipd = gi_probe_data[i]; + VoxelGIData &gipd = voxel_gi_data[i]; RID base_probe = gipi->probe; - Transform to_cell = storage->gi_probe_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera; + Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera; gipd.xform[0] = to_cell.basis.elements[0][0]; gipd.xform[1] = to_cell.basis.elements[1][0]; @@ -3068,36 +3068,36 @@ void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_ gipd.xform[14] = to_cell.origin.z; gipd.xform[15] = 1; - Vector3 bounds = storage->gi_probe_get_octree_size(base_probe); + Vector3 bounds = storage->voxel_gi_get_octree_size(base_probe); gipd.bounds[0] = bounds.x; gipd.bounds[1] = bounds.y; gipd.bounds[2] = bounds.z; - gipd.dynamic_range = storage->gi_probe_get_dynamic_range(base_probe) * storage->gi_probe_get_energy(base_probe); - gipd.bias = storage->gi_probe_get_bias(base_probe); - gipd.normal_bias = storage->gi_probe_get_normal_bias(base_probe); - gipd.blend_ambient = !storage->gi_probe_is_interior(base_probe); + gipd.dynamic_range = storage->voxel_gi_get_dynamic_range(base_probe) * storage->voxel_gi_get_energy(base_probe); + gipd.bias = storage->voxel_gi_get_bias(base_probe); + gipd.normal_bias = storage->voxel_gi_get_normal_bias(base_probe); + gipd.blend_ambient = !storage->voxel_gi_is_interior(base_probe); gipd.anisotropy_strength = 0; - gipd.ao = storage->gi_probe_get_ao(base_probe); - gipd.ao_size = Math::pow(storage->gi_probe_get_ao_size(base_probe), 4.0f); + gipd.ao = storage->voxel_gi_get_ao(base_probe); + gipd.ao_size = Math::pow(storage->voxel_gi_get_ao_size(base_probe), 4.0f); gipd.mipmaps = gipi->mipmaps.size(); } - r_gi_probes_used++; + r_voxel_gi_instances_used++; } if (texture == RID()) { texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } - if (texture != rb->gi.giprobe_textures[i]) { - giprobes_changed = true; - rb->gi.giprobe_textures[i] = texture; + if (texture != rb->gi.voxel_gi_textures[i]) { + voxel_gi_instances_changed = true; + rb->gi.voxel_gi_textures[i] = texture; } } - if (giprobes_changed) { + if (voxel_gi_instances_changed) { if (RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) { RD::get_singleton()->free(rb->gi.uniform_set); } @@ -3112,14 +3112,14 @@ void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_ } } - if (p_gi_probes.size() > 0) { - RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GIProbeData) * MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, RD::BARRIER_MASK_COMPUTE); + if (p_voxel_gi_instances.size() > 0) { + RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data, RD::BARRIER_MASK_COMPUTE); } RD::get_singleton()->draw_command_end_label(); } -void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render) { +void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { RD::get_singleton()->draw_command_begin_label("GI Render"); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); @@ -3157,11 +3157,11 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]); push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; - push_constant.max_giprobes = MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size()); - push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH; + push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()); + push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH; bool use_sdfgi = rb->sdfgi != nullptr; - bool use_giprobes = push_constant.max_giprobes > 0; + bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0; if (env) { push_constant.ao_color[0] = env->ao_color.r; @@ -3311,7 +3311,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 14; - RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); + RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(buffer); uniforms.push_back(u); } @@ -3326,15 +3326,15 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 16; - u.ids.push_back(rb->gi.giprobe_buffer); + u.ids.push_back(rb->gi.voxel_gi_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 17; - for (int i = 0; i < MAX_GIPROBES; i++) { - u.ids.push_back(rb->gi.giprobe_textures[i]); + for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { + u.ids.push_back(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); } @@ -3345,9 +3345,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ Mode mode; if (rb->gi.using_half_size_gi) { - mode = (use_sdfgi && use_giprobes) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_GIPROBE); + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI); } else { - mode = (use_sdfgi && use_giprobes) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_GIPROBE); + mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI); } RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]); @@ -3364,39 +3364,39 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::get_singleton()->draw_command_end_label(); } -RID RendererSceneGIRD::gi_probe_instance_create(RID p_base) { - GIProbeInstance gi_probe; - gi_probe.gi = this; - gi_probe.storage = storage; - gi_probe.probe = p_base; - RID rid = gi_probe_instance_owner.make_rid(gi_probe); +RID RendererSceneGIRD::voxel_gi_instance_create(RID p_base) { + VoxelGIInstance voxel_gi; + voxel_gi.gi = this; + voxel_gi.storage = storage; + voxel_gi.probe = p_base; + RID rid = voxel_gi_instance_owner.make_rid(voxel_gi); return rid; } -void RendererSceneGIRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { - GIProbeInstance *gi_probe = get_probe_instance(p_probe); - ERR_FAIL_COND(!gi_probe); +void RendererSceneGIRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { + VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); + ERR_FAIL_COND(!voxel_gi); - gi_probe->transform = p_xform; + voxel_gi->transform = p_xform; } -bool RendererSceneGIRD::gi_probe_needs_update(RID p_probe) const { - GIProbeInstance *gi_probe = get_probe_instance(p_probe); - ERR_FAIL_COND_V(!gi_probe, false); +bool RendererSceneGIRD::voxel_gi_needs_update(RID p_probe) const { + VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); + ERR_FAIL_COND_V(!voxel_gi, false); - return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe); + return voxel_gi->last_probe_version != storage->voxel_gi_get_version(voxel_gi->probe); } -void RendererSceneGIRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { - GIProbeInstance *gi_probe = get_probe_instance(p_probe); - ERR_FAIL_COND(!gi_probe); +void RendererSceneGIRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { + VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); + ERR_FAIL_COND(!voxel_gi); - gi_probe->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); + voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); } -void RendererSceneGIRD::debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { - GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererSceneGIRD::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { + VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha); + voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha); } diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index 59f5f374d1..45fc7b3951 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -38,13 +38,13 @@ #include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -56,9 +56,9 @@ class RendererSceneGIRD { private: RendererStorageRD *storage; - /* GIPROBE INSTANCE */ + /* VOXEL_GI INSTANCE */ - struct GIProbeLight { + struct VoxelGILight { uint32_t type; float energy; float radius; @@ -74,7 +74,7 @@ private: uint32_t has_shadow; }; - struct GIProbePushConstant { + struct VoxelGIPushConstant { int32_t limits[3]; uint32_t stack_size; @@ -89,7 +89,7 @@ private: uint32_t pad; }; - struct GIProbeDynamicPushConstant { + struct VoxelGIDynamicPushConstant { int32_t limits[3]; uint32_t light_count; int32_t x_dir[3]; @@ -110,36 +110,36 @@ private: float pad[3]; }; - GIProbeLight *gi_probe_lights; - uint32_t gi_probe_max_lights; - RID gi_probe_lights_uniform; + VoxelGILight *voxel_gi_lights; + uint32_t voxel_gi_max_lights; + RID voxel_gi_lights_uniform; enum { - GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT, - GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE, - GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP, - GI_PROBE_SHADER_VERSION_WRITE_TEXTURE, - GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING, - GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE, - GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT, - GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT, - GI_PROBE_SHADER_VERSION_MAX + VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT, + VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE, + VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP, + VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE, + VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING, + VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE, + VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT, + VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT, + VOXEL_GI_SHADER_VERSION_MAX }; - GiprobeShaderRD giprobe_shader; - RID giprobe_lighting_shader_version; - RID giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_MAX]; - RID giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_MAX]; + VoxelGiShaderRD voxel_gi_shader; + RID voxel_gi_lighting_shader_version; + RID voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_MAX]; + RID voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_MAX]; enum { - GI_PROBE_DEBUG_COLOR, - GI_PROBE_DEBUG_LIGHT, - GI_PROBE_DEBUG_EMISSION, - GI_PROBE_DEBUG_LIGHT_FULL, - GI_PROBE_DEBUG_MAX + VOXEL_GI_DEBUG_COLOR, + VOXEL_GI_DEBUG_LIGHT, + VOXEL_GI_DEBUG_EMISSION, + VOXEL_GI_DEBUG_LIGHT_FULL, + VOXEL_GI_DEBUG_MAX }; - struct GIProbeDebugPushConstant { + struct VoxelGIDebugPushConstant { float projection[16]; uint32_t cell_offset; float dynamic_range; @@ -149,11 +149,11 @@ private: uint32_t pad; }; - GiprobeDebugShaderRD giprobe_debug_shader; - RID giprobe_debug_shader_version; - RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX]; - PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX]; - RID giprobe_debug_uniform_set; + VoxelGiDebugShaderRD voxel_gi_debug_shader; + RID voxel_gi_debug_shader_version; + RID voxel_gi_debug_shader_version_shaders[VOXEL_GI_DEBUG_MAX]; + PipelineCacheRD voxel_gi_debug_shader_version_pipelines[VOXEL_GI_DEBUG_MAX]; + RID voxel_gi_debug_uniform_set; /* SDFGI */ @@ -326,11 +326,11 @@ private: } sdfgi_shader; public: - /* GIPROBE INSTANCE */ + /* VOXEL_GI INSTANCE */ - //@TODO GIProbeInstance is still directly used in the render code, we'll address this when we refactor the render code itself. + //@TODO VoxelGIInstance is still directly used in the render code, we'll address this when we refactor the render code itself. - struct GIProbeInstance { + struct VoxelGIInstance { // access to our containers RendererStorageRD *storage; RendererSceneGIRD *gi; @@ -374,25 +374,25 @@ public: bool has_dynamic_object_data = false; - Transform transform; + Transform3D transform; void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; - mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner; + mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; - _FORCE_INLINE_ GIProbeInstance *get_probe_instance(RID p_probe) const { - return gi_probe_instance_owner.getornull(p_probe); + _FORCE_INLINE_ VoxelGIInstance *get_probe_instance(RID p_probe) const { + return voxel_gi_instance_owner.getornull(p_probe); }; - _FORCE_INLINE_ RID gi_probe_instance_get_texture(RID p_probe) { - GIProbeInstance *gi_probe = get_probe_instance(p_probe); - ERR_FAIL_COND_V(!gi_probe, RID()); - return gi_probe->texture; + _FORCE_INLINE_ RID voxel_gi_instance_get_texture(RID p_probe) { + VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); + ERR_FAIL_COND_V(!voxel_gi, RID()); + return voxel_gi->texture; }; - RS::GIProbeQuality gi_probe_quality = RS::GI_PROBE_QUALITY_HIGH; + RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_HIGH; /* SDFGI */ @@ -527,10 +527,10 @@ public: int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); - void debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture); + void debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture); void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); - void pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); + void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; @@ -551,13 +551,13 @@ public: /* GI */ enum { - MAX_GIPROBES = 8 + MAX_VOXEL_GI_INSTANCES = 8 }; // Struct for use in render buffer struct RenderBuffersGI { - RID giprobe_textures[MAX_GIPROBES]; - RID giprobe_buffer; + RID voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; + RID voxel_gi_buffer; RID full_buffer; RID full_dispatch; @@ -601,7 +601,7 @@ public: ProbeCascadeData cascades[SDFGI::MAX_CASCADES]; }; - struct GIProbeData { + struct VoxelGIData { float xform[16]; float bounds[3]; float dynamic_range; @@ -624,7 +624,7 @@ public: float proj_info[4]; float ao_color[3]; - uint32_t max_giprobes; + uint32_t max_voxel_gi_instances; uint32_t high_quality_vct; uint32_t orthogonal; @@ -635,16 +635,16 @@ public: RID sdfgi_ubo; enum Mode { - MODE_GIPROBE, + MODE_VOXEL_GI, MODE_SDFGI, MODE_COMBINED, - MODE_HALF_RES_GIPROBE, + MODE_HALF_RES_VOXEL_GI, MODE_HALF_RES_SDFGI, MODE_HALF_RES_COMBINED, MODE_MAX }; - RID default_giprobe_buffer; + RID default_voxel_gi_buffer; bool half_resolution = false; GiShaderRD shader; @@ -659,14 +659,14 @@ public: SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); - void setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render); - void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render); + void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); + void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); - RID gi_probe_instance_create(RID p_base); - void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform); - bool gi_probe_needs_update(RID p_probe) const; - void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); - void debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + RID voxel_gi_instance_create(RID p_base); + void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); + bool voxel_gi_needs_update(RID p_probe) const; + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; #endif /* !RENDERING_SERVER_SCENE_GI_RD_H */ diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 1f01de1333..ff7e6c502f 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -570,7 +570,7 @@ RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) { return reflection_probe_instance_owner.make_rid(rpi); } -void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) { +void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND(!rpi); @@ -1233,7 +1233,7 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) { return li; } -void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { +void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -1247,7 +1247,7 @@ void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const light_instance->aabb = p_aabb; } -void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -1305,7 +1305,7 @@ RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { return decal_instance_owner.make_rid(di); } -void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) { +void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) { DecalInstance *di = decal_instance_owner.getornull(p_decal); ERR_FAIL_COND(!di); di->transform = p_transform; @@ -1318,7 +1318,7 @@ RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) { li.lightmap = p_lightmap; return lightmap_instance_owner.make_rid(li); } -void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) { +void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) { LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap); ERR_FAIL_COND(!li); li->transform = p_transform; @@ -1326,28 +1326,28 @@ void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, cons ///////////////////////////////// -RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) { - return gi.gi_probe_instance_create(p_base); +RID RendererSceneRenderRD::voxel_gi_instance_create(RID p_base) { + return gi.voxel_gi_instance_create(p_base); } -void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { - gi.gi_probe_instance_set_transform_to_data(p_probe, p_xform); +void RendererSceneRenderRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { + gi.voxel_gi_instance_set_transform_to_data(p_probe, p_xform); } -bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const { +bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const { if (!is_dynamic_gi_supported()) { return false; } - return gi.gi_probe_needs_update(p_probe); + return gi.voxel_gi_needs_update(p_probe); } -void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { +void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { if (!is_dynamic_gi_supported()) { return; } - gi.gi_probe_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this); + gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this); } void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { @@ -1959,17 +1959,17 @@ RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) { return rb->ssao.ao_final; } -RID RendererSceneRenderRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) { +RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); - if (rb->gi.giprobe_buffer.is_null()) { - rb->gi.giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::GIProbeData) * RendererSceneGIRD::MAX_GIPROBES); + if (rb->gi.voxel_gi_buffer.is_null()) { + rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES); } - return rb->gi.giprobe_buffer; + return rb->gi.voxel_gi_buffer; } -RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() { - return gi.default_giprobe_buffer; +RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { + return gi.default_voxel_gi_buffer; } RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) { @@ -2284,7 +2284,7 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g return rb->data; } -void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) { +void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment) { cluster.reflection_count = 0; for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) { @@ -2344,8 +2344,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy; reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy; - Transform transform = rpi->transform; - Transform proj = (p_camera_inverse_transform * transform).inverse(); + Transform3D transform = rpi->transform; + Transform3D proj = (p_camera_inverse_transform * transform).inverse(); RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix); if (current_cluster_builder != nullptr) { @@ -2360,8 +2360,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti } } -void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { - Transform inverse_transform = p_camera_transform.affine_inverse(); +void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) { + Transform3D inverse_transform = p_camera_transform.affine_inverse(); r_directional_light_count = 0; r_positional_light_count = 0; @@ -2387,7 +2387,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const // Copy to SkyDirectionalLightData if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) { RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count]; - Transform light_transform = li->transform; + Transform3D light_transform = li->transform; Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); sky_light_data.direction[0] = world_direction.x; @@ -2423,7 +2423,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Cluster::DirectionalLightData &light_data = cluster.directional_lights[r_directional_light_count]; - Transform light_transform = li->transform; + Transform3D light_transform = li->transform; Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized(); @@ -2513,7 +2513,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const CameraMatrix rectm; rectm.set_light_atlas_rect(atlas_rect); - Transform modelview = (inverse_transform * li->shadow_transform[j].transform).inverse(); + Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse(); CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; @@ -2609,7 +2609,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance; RID base = li->light; - Transform light_transform = li->transform; + Transform3D light_transform = li->transform; float sign = storage->light_is_negative(base) ? -1 : 1; Color linear_col = storage->light_get_color(base).to_linear(); @@ -2709,7 +2709,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const if (type == RS::LIGHT_OMNI) { light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another - Transform proj = (inverse_transform * light_transform).inverse(); + Transform3D proj = (inverse_transform * light_transform).inverse(); RendererStorageRD::store_transform(proj, light_data.shadow_matrix); @@ -2721,7 +2721,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const } } else if (type == RS::LIGHT_SPOT) { - Transform modelview = (inverse_transform * light_transform).inverse(); + Transform3D modelview = (inverse_transform * light_transform).inverse(); CameraMatrix bias; bias.set_light_bias(); @@ -2765,8 +2765,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const } } -void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform) { - Transform uv_xform; +void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) { + Transform3D uv_xform; uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); uv_xform.origin = Vector3(-1.0, 0.0, -1.0); @@ -2785,7 +2785,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const } RID decal = di->decal; - Transform xform = di->transform; + Transform3D xform = di->transform; real_t distance = -p_camera_inverse_xform.xform(xform.origin).z; @@ -2817,7 +2817,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const di->render_index = i; di->cull_mask = storage->decal_get_cull_mask(decal); - Transform xform = di->transform; + Transform3D xform = di->transform; float fade = 1.0; if (storage->decal_is_distance_fade_enabled(decal)) { @@ -2834,9 +2834,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Vector3 decal_extents = storage->decal_get_extents(decal); - Transform scale_xform; + Transform3D scale_xform; scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z)); - Transform to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse(); + Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse(); RendererStorageRD::store_transform(to_decal_xform, dd.xform); Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized(); @@ -3066,7 +3066,7 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { rb->volumetric_fog = nullptr; } -void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { +void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count) { ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3228,7 +3228,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 11; - u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers)); + u.ids.push_back(render_buffers_get_voxel_gi_buffer(p_render_buffers)); uniforms.push_back(u); } @@ -3236,8 +3236,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; - for (int i = 0; i < RendererSceneGIRD::MAX_GIPROBES; i++) { - u.ids.push_back(rb->gi.giprobe_textures[i]); + for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) { + u.ids.push_back(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); } @@ -3362,10 +3362,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.cam_rotation[10] = p_cam_transform.basis[2][2]; params.cam_rotation[11] = 0; params.filter_axis = 0; - params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0; + params.max_voxel_gi_instances = env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0; params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform; + Transform3D to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform; storage->store_transform(to_prev_cam_view, params.to_prev_view); params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; @@ -3492,7 +3492,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo } } -void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) { +void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) { // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time if (p_render_data->render_buffers.is_valid() && p_use_gi) { @@ -3569,7 +3569,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool //start GI if (render_gi) { - gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->gi_probes, this); + gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_voxel_gi_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this); } //Do shadow rendering (in parallel with GI) @@ -3625,12 +3625,12 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } if (is_volumetric_supported()) { - _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count); + _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count); } } } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) { // getting this here now so we can direct call a bunch of things more easily RenderBuffers *rb = nullptr; if (p_render_buffers.is_valid()) { @@ -3652,7 +3652,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & render_data.instances = &p_instances; render_data.lights = &p_lights; render_data.reflection_probes = &p_reflection_probes; - render_data.gi_probes = &p_gi_probes; + render_data.voxel_gi_instances = &p_voxel_gi_instances; render_data.decals = &p_decals; render_data.lightmaps = &p_lightmaps; render_data.environment = p_environment; @@ -3683,7 +3683,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { render_data.lights = ∅ render_data.reflection_probes = ∅ - render_data.gi_probes = ∅ + render_data.voxel_gi_instances = ∅ } //sdfgi first @@ -3703,12 +3703,12 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & clear_color = storage->get_default_clear_color(); } - //assign render indices to giprobes + //assign render indices to voxel_gi_instances if (is_dynamic_gi_supported()) { - for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) { - RendererSceneGIRD::GIProbeInstance *giprobe_inst = gi.gi_probe_instance_owner.getornull(p_gi_probes[i]); - if (giprobe_inst) { - giprobe_inst->render_index = i; + for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) { + RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.getornull(p_voxel_gi_instances[i]); + if (voxel_gi_inst) { + voxel_gi_inst->render_index = i; } } } @@ -3736,9 +3736,9 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & rb->sdfgi->pre_process_gi(p_cam_transform, &render_data, this); } - render_state.gi_probe_count = 0; + render_state.voxel_gi_count = 0; if (rb != nullptr && rb->sdfgi != nullptr) { - gi.setup_giprobes(render_data.render_buffers, render_data.cam_transform, *render_data.gi_probes, render_state.gi_probe_count, this); + gi.setup_voxel_gi_instances(render_data.render_buffers, render_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this); rb->sdfgi->update_light(); } @@ -3808,7 +3808,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, bool flip_y = false; CameraMatrix light_projection; - Transform light_transform; + Transform3D light_transform; if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) { //set pssm stuff @@ -3958,11 +3958,11 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } -void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider)); Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); CameraMatrix cm; @@ -3971,7 +3971,7 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, Vector3 cam_pos = p_transform.origin; cam_pos.y += extents.y; - Transform cam_xform; + Transform3D cam_xform; cam_xform.set_look_at(cam_pos, cam_pos - p_transform.basis.get_axis(Vector3::AXIS_Y), -p_transform.basis.get_axis(Vector3::AXIS_Z).normalized()); RID fb = storage->particles_collision_get_heightfield_framebuffer(p_collider); @@ -4018,19 +4018,19 @@ bool RendererSceneRenderRD::free(RID p_rid) { decal_instance_owner.free(p_rid); } else if (lightmap_instance_owner.owns(p_rid)) { lightmap_instance_owner.free(p_rid); - } else if (gi.gi_probe_instance_owner.owns(p_rid)) { - RendererSceneGIRD::GIProbeInstance *gi_probe = gi.gi_probe_instance_owner.getornull(p_rid); - if (gi_probe->texture.is_valid()) { - RD::get_singleton()->free(gi_probe->texture); - RD::get_singleton()->free(gi_probe->write_buffer); + } else if (gi.voxel_gi_instance_owner.owns(p_rid)) { + RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.getornull(p_rid); + if (voxel_gi->texture.is_valid()) { + RD::get_singleton()->free(voxel_gi->texture); + RD::get_singleton()->free(voxel_gi->write_buffer); } - for (int i = 0; i < gi_probe->dynamic_maps.size(); i++) { - RD::get_singleton()->free(gi_probe->dynamic_maps[i].texture); - RD::get_singleton()->free(gi_probe->dynamic_maps[i].depth); + for (int i = 0; i < voxel_gi->dynamic_maps.size(); i++) { + RD::get_singleton()->free(voxel_gi->dynamic_maps[i].texture); + RD::get_singleton()->free(voxel_gi->dynamic_maps[i].depth); } - gi.gi_probe_instance_owner.free(p_rid); + gi.voxel_gi_instance_owner.free(p_rid); } else if (sky.sky_owner.owns(p_rid)) { sky.update_dirty_skys(); sky.free_sky(p_rid); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 1f82ae6dec..c8fcbecc95 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -46,7 +46,7 @@ struct RenderDataRD { RID render_buffers = RID(); - Transform cam_transform = Transform(); + Transform3D cam_transform = Transform3D(); CameraMatrix cam_projection = CameraMatrix(); bool cam_ortogonal = false; @@ -56,7 +56,7 @@ struct RenderDataRD { const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; - const PagedArray<RID> *gi_probes = nullptr; + const PagedArray<RID> *voxel_gi_instances = nullptr; const PagedArray<RID> *decals = nullptr; const PagedArray<RID> *lightmaps = nullptr; RID environment = RID(); @@ -92,21 +92,21 @@ protected: }; virtual RenderBufferData *_create_render_buffer_data() = 0; - void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count); - void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform); - void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment); + void _setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count); + void _setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform); + void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment); virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; - virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); @@ -123,7 +123,7 @@ protected: void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi); void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi); - void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer); + void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer); // needed for a single argument calls (material and uv2) PagedArrayPool<GeometryInstance *> cull_argument_pool; @@ -184,7 +184,7 @@ private: uint32_t render_index = 0; uint32_t cull_mask = 0; - Transform transform; + Transform3D transform; }; mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner; @@ -193,7 +193,7 @@ private: struct DecalInstance { RID decal; - Transform transform; + Transform3D transform; uint32_t render_index; uint32_t cull_mask; }; @@ -204,7 +204,7 @@ private: struct LightmapInstance { RID lightmap; - Transform transform; + Transform3D transform; }; mutable RID_Owner<LightmapInstance> lightmap_instance_owner; @@ -312,7 +312,7 @@ private: struct LightInstance { struct ShadowTransform { CameraMatrix camera; - Transform transform; + Transform3D transform; float farplane; float split; float bias_scale; @@ -329,7 +329,7 @@ private: AABB aabb; RID self; RID light; - Transform transform; + Transform3D transform; Vector3 light_vector; Vector3 spot_vector; @@ -631,7 +631,7 @@ private: int render_sdfgi_region_count = 0; const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr; - uint32_t gi_probe_count = 0; + uint32_t voxel_gi_count = 0; LocalVector<int> cube_shadows; LocalVector<int> shadows; @@ -663,7 +663,7 @@ private: int last_shadow_filter = -1; - Transform prev_cam_transform; + Transform3D prev_cam_transform; }; enum { @@ -692,7 +692,7 @@ private: float detail_spread; float gi_inject; - uint32_t max_gi_probes; + uint32_t max_voxel_gi_instances; uint32_t cluster_type_size; float screen_size[2]; @@ -721,7 +721,7 @@ private: bool volumetric_fog_filter_active = true; void _volumetric_fog_erase(RenderBuffers *rb); - void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count); + void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count); RID shadow_sampler; @@ -740,7 +740,7 @@ private: void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true); public: - virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0; + virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; /* SHADOW ATLAS API */ @@ -878,9 +878,9 @@ public: virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure); RID light_instance_create(RID p_light); - void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); + void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform); void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb); - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()); + void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()); void light_instance_mark_visible(RID p_light_instance); _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { @@ -888,7 +888,7 @@ public: return li->light; } - _FORCE_INLINE_ Transform light_instance_get_base_transform(RID p_light_instance) { + _FORCE_INLINE_ Transform3D light_instance_get_base_transform(RID p_light_instance) { LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->transform; } @@ -945,7 +945,7 @@ public: return float(1.0) / shadow_size; } - _FORCE_INLINE_ Transform + _FORCE_INLINE_ Transform3D light_instance_get_shadow_transform(RID p_light_instance, int p_index) { LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].transform; @@ -1019,7 +1019,7 @@ public: } virtual RID reflection_probe_instance_create(RID p_probe); - virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform); + virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform); virtual void reflection_probe_release_atlas_index(RID p_instance); virtual bool reflection_probe_instance_needs_redraw(RID p_instance); virtual bool reflection_probe_instance_has_reflection(RID p_instance); @@ -1063,9 +1063,9 @@ public: return rpi->last_pass; } - _FORCE_INLINE_ Transform reflection_probe_instance_get_transform(RID p_instance) { + _FORCE_INLINE_ Transform3D reflection_probe_instance_get_transform(RID p_instance) { ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); - ERR_FAIL_COND_V(!rpi, Transform()); + ERR_FAIL_COND_V(!rpi, Transform3D()); return rpi->transform; } @@ -1078,20 +1078,20 @@ public: } virtual RID decal_instance_create(RID p_decal); - virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform); + virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform); _FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const { DecalInstance *decal = decal_instance_owner.getornull(p_decal); return decal->decal; } - _FORCE_INLINE_ Transform decal_instance_get_transform(RID p_decal) const { + _FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const { DecalInstance *decal = decal_instance_owner.getornull(p_decal); return decal->transform; } virtual RID lightmap_instance_create(RID p_lightmap); - virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform); + virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform); _FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) { return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr; } @@ -1100,7 +1100,7 @@ public: LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); return li->lightmap; } - _FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) { + _FORCE_INLINE_ Transform3D lightmap_instance_get_transform(RID p_lightmap_instance) { LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); return li->transform; } @@ -1109,11 +1109,11 @@ public: /* gi light probes */ - RID gi_probe_instance_create(RID p_base); - void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform); - bool gi_probe_needs_update(RID p_probe) const; - void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects); - void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi.gi_probe_quality = p_quality; } + RID voxel_gi_instance_create(RID p_base); + void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); + bool voxel_gi_needs_update(RID p_probe) const; + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects); + void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) { gi.voxel_gi_quality = p_quality; } /* render buffers */ @@ -1123,8 +1123,8 @@ public: RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); - RID render_buffers_get_gi_probe_buffer(RID p_render_buffers); - RID render_buffers_get_default_gi_probe_buffer(); + RID render_buffers_get_voxel_gi_buffer(RID p_render_buffers); + RID render_buffers_get_default_voxel_gi_buffer(); RID render_buffers_get_gi_ambient_texture(RID p_render_buffers); RID render_buffers_get_gi_reflection_texture(RID p_render_buffers); @@ -1147,11 +1147,11 @@ public: float render_buffers_get_volumetric_fog_end(RID p_render_buffers); float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr); + void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr); - void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); + void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); - void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances); + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances); virtual void set_scene_pass(uint64_t p_pass) { scene_pass = p_pass; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 966a1c6815..e68f466015 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -878,7 +878,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { } } -void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky... SkyMaterialData *material = nullptr; @@ -1048,7 +1048,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) { +void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time) { ERR_FAIL_COND(!p_env); Sky *sky = get_sky(p_env->sky); @@ -1135,7 +1135,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM RD::DrawListID cubemap_draw_list; for (int i = 0; i < 6; i++) { - Transform local_view; + Transform3D local_view; local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd); @@ -1153,7 +1153,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM RD::DrawListID cubemap_draw_list; for (int i = 0; i < 6; i++) { - Transform local_view; + Transform3D local_view; local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd); @@ -1167,7 +1167,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP]; for (int i = 0; i < 6; i++) { - Transform local_view; + Transform3D local_view; local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]); RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd); @@ -1213,7 +1213,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM } } -void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) { +void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time) { ERR_FAIL_COND(!p_env); Sky *sky = get_sky(p_env->sky); diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 73390a586b..063e4e662e 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -268,9 +268,9 @@ public: void init(RendererStorageRD *p_storage); - void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); - void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time); - void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time); + void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time); + void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 7a26e40c0a..05993829d1 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -1878,8 +1878,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[1] = v.position.y; gui[2] = v.size.x; gui[3] = v.size.y; - } else if (value.get_type() == Variant::QUAT) { - Quat v = value; + } else if (value.get_type() == Variant::QUATERNION) { + Quaternion v = value; gui[0] = v.x; gui[1] = v.y; @@ -1926,7 +1926,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[11] = 0; } break; case ShaderLanguage::TYPE_MAT4: { - Transform v = value; + Transform3D v = value; float *gui = (float *)data; gui[0] = v.basis.elements[0][0]; @@ -2776,7 +2776,7 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { const float *dataptr = baseptr + j * 8; - Transform mtx; + Transform3D mtx; mtx.basis.elements[0].x = dataptr[0]; mtx.basis.elements[1].x = dataptr[1]; @@ -2803,7 +2803,7 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { const float *dataptr = baseptr + j * 12; - Transform mtx; + Transform3D mtx; mtx.basis.elements[0][0] = dataptr[0]; mtx.basis.elements[0][1] = dataptr[1]; @@ -3478,7 +3478,7 @@ void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const fl AABB mesh_aabb = mesh_get_aabb(multimesh->mesh); for (int i = 0; i < p_instances; i++) { const float *data = p_data + multimesh->stride_cache * i; - Transform t; + Transform3D t; if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) { t.basis.elements[0][0] = data[0]; @@ -3514,7 +3514,7 @@ void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const fl multimesh->aabb = aabb; } -void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { +void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -3621,15 +3621,15 @@ RID RendererStorageRD::multimesh_get_mesh(RID p_multimesh) const { return multimesh->mesh; } -Transform RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { +Transform3D RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); - ERR_FAIL_COND_V(!multimesh, Transform()); - ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform()); - ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform()); + ERR_FAIL_COND_V(!multimesh, Transform3D()); + ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D()); + ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D()); _multimesh_make_local(multimesh); - Transform t; + Transform3D t; { const float *r = multimesh->data_cache.ptr(); @@ -4065,7 +4065,7 @@ void RendererStorageRD::particles_set_trails(RID p_particles, bool p_enable, flo particles->dependency.changed_notify(DEPENDENCY_CHANGED_PARTICLES); } -void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses) { +void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); if (particles->trail_bind_pose_buffer.is_valid() && particles->trail_bind_poses.size() != p_bind_poses.size()) { @@ -4161,7 +4161,7 @@ void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitt } } -void RendererStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { +void RendererStorageRD::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(particles->amount == 0); @@ -4229,7 +4229,7 @@ AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) { Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(particles->particle_buffer); - Transform inv = particles->emission_transform.affine_inverse(); + Transform3D inv = particles->emission_transform.affine_inverse(); AABB aabb; if (buffer.size()) { @@ -4272,7 +4272,7 @@ AABB RendererStorageRD::particles_get_aabb(RID p_particles) const { return particles->custom_aabb; } -void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) { +void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -4396,7 +4396,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta frame_params.randomness = p_particles->randomness; if (p_particles->use_local_coords) { - store_transform(Transform(), frame_params.emission_transform); + store_transform(Transform3D(), frame_params.emission_transform); } else { store_transform(p_particles->emission_transform, frame_params.emission_transform); } @@ -4416,7 +4416,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta RID collision_3d_textures[ParticlesFrameParams::MAX_3D_TEXTURES]; RID collision_heightmap_texture; - Transform to_particles; + Transform3D to_particles; if (p_particles->use_local_coords) { to_particles = p_particles->emission_transform.affine_inverse(); } @@ -4473,7 +4473,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision); ERR_CONTINUE(!pc); - Transform to_collider = pci->transform; + Transform3D to_collider = pci->transform; if (p_particles->use_local_coords) { to_collider = to_particles * to_collider; } @@ -5522,7 +5522,7 @@ RID RendererStorageRD::particles_collision_instance_create(RID p_collision) { pci.collision = p_collision; return particles_collision_instance_owner.make_rid(pci); } -void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) { +void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) { ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance); ERR_FAIL_COND(!pci); pci->transform = p_transform; @@ -5600,7 +5600,7 @@ int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const { return skeleton->size; } -void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { +void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -5625,16 +5625,16 @@ void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, _skeleton_make_dirty(skeleton); } -Transform RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { +Transform3D RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); - ERR_FAIL_COND_V(!skeleton, Transform()); - ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform()); - ERR_FAIL_COND_V(skeleton->use_2d, Transform()); + ERR_FAIL_COND_V(!skeleton, Transform3D()); + ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D()); + ERR_FAIL_COND_V(skeleton->use_2d, Transform3D()); const float *dataptr = skeleton->data.ptr() + p_bone * 12; - Transform t; + Transform3D t; t.basis.elements[0][0] = dataptr[0]; t.basis.elements[0][1] = dataptr[1]; @@ -6324,36 +6324,36 @@ AABB RendererStorageRD::decal_get_aabb(RID p_decal) const { return AABB(-decal->extents, decal->extents * 2.0); } -RID RendererStorageRD::gi_probe_allocate() { - return gi_probe_owner.allocate_rid(); +RID RendererStorageRD::voxel_gi_allocate() { + return voxel_gi_owner.allocate_rid(); } -void RendererStorageRD::gi_probe_initialize(RID p_gi_probe) { - gi_probe_owner.initialize_rid(p_gi_probe, GIProbe()); +void RendererStorageRD::voxel_gi_initialize(RID p_voxel_gi) { + voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI()); } -void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - if (gi_probe->octree_buffer.is_valid()) { - RD::get_singleton()->free(gi_probe->octree_buffer); - RD::get_singleton()->free(gi_probe->data_buffer); - if (gi_probe->sdf_texture.is_valid()) { - RD::get_singleton()->free(gi_probe->sdf_texture); + if (voxel_gi->octree_buffer.is_valid()) { + RD::get_singleton()->free(voxel_gi->octree_buffer); + RD::get_singleton()->free(voxel_gi->data_buffer); + if (voxel_gi->sdf_texture.is_valid()) { + RD::get_singleton()->free(voxel_gi->sdf_texture); } - gi_probe->sdf_texture = RID(); - gi_probe->octree_buffer = RID(); - gi_probe->data_buffer = RID(); - gi_probe->octree_buffer_size = 0; - gi_probe->data_buffer_size = 0; - gi_probe->cell_count = 0; + voxel_gi->sdf_texture = RID(); + voxel_gi->octree_buffer = RID(); + voxel_gi->data_buffer = RID(); + voxel_gi->octree_buffer_size = 0; + voxel_gi->data_buffer_size = 0; + voxel_gi->cell_count = 0; } - gi_probe->to_cell_xform = p_to_cell_xform; - gi_probe->bounds = p_aabb; - gi_probe->octree_size = p_octree_size; - gi_probe->level_counts = p_level_counts; + voxel_gi->to_cell_xform = p_to_cell_xform; + voxel_gi->bounds = p_aabb; + voxel_gi->octree_size = p_octree_size; + voxel_gi->level_counts = p_level_counts; if (p_octree_cells.size()) { ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32 @@ -6362,42 +6362,42 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform & ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches - gi_probe->cell_count = cell_count; - gi_probe->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); - gi_probe->octree_buffer_size = p_octree_cells.size(); - gi_probe->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells); - gi_probe->data_buffer_size = p_data_cells.size(); + voxel_gi->cell_count = cell_count; + voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); + voxel_gi->octree_buffer_size = p_octree_cells.size(); + voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells); + voxel_gi->data_buffer_size = p_data_cells.size(); if (p_distance_field.size()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = gi_probe->octree_size.x; - tf.height = gi_probe->octree_size.y; - tf.depth = gi_probe->octree_size.z; + tf.width = voxel_gi->octree_size.x; + tf.height = voxel_gi->octree_size.y; + tf.depth = voxel_gi->octree_size.z; tf.texture_type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; Vector<Vector<uint8_t>> s; s.push_back(p_distance_field); - gi_probe->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); + voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); } #if 0 { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = gi_probe->octree_size.x; - tf.height = gi_probe->octree_size.y; - tf.depth = gi_probe->octree_size.z; + tf.width = voxel_gi->octree_size.x; + tf.height = voxel_gi->octree_size.y; + tf.depth = voxel_gi->octree_size.z; tf.type = RD::TEXTURE_TYPE_3D; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM); tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT); - gi_probe->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } RID shared_tex; { RD::TextureView tv; tv.format_override = RD::DATA_FORMAT_R8_UINT; - shared_tex = RD::get_singleton()->texture_create_shared(tv, gi_probe->sdf_texture); + shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture); } //update SDF texture Vector<RD::Uniform> uniforms; @@ -6405,14 +6405,14 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform & RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(gi_probe->octree_buffer); + u.ids.push_back(voxel_gi->octree_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(gi_probe->data_buffer); + u.ids.push_back(voxel_gi->data_buffer); uniforms.push_back(u); } { @@ -6423,24 +6423,24 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform & uniforms.push_back(u); } - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_sdf_shader_version_shader, 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0); { uint32_t push_constant[4] = { 0, 0, 0, 0 }; - for (int i = 0; i < gi_probe->level_counts.size() - 1; i++) { - push_constant[0] += gi_probe->level_counts[i]; + for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) { + push_constant[0] += voxel_gi->level_counts[i]; } - push_constant[1] = push_constant[0] + gi_probe->level_counts[gi_probe->level_counts.size() - 1]; + push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1]; print_line("offset: " + itos(push_constant[0])); print_line("size: " + itos(push_constant[1])); //create SDF RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_sdf_shader_pipeline); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4); - RD::get_singleton()->compute_list_dispatch(compute_list, gi_probe->octree_size.x / 4, gi_probe->octree_size.y / 4, gi_probe->octree_size.z / 4); + RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4); RD::get_singleton()->compute_list_end(); } @@ -6450,232 +6450,232 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform & #endif } - gi_probe->version++; - gi_probe->data_version++; + voxel_gi->version++; + voxel_gi->data_version++; - gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); + voxel_gi->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } -AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, AABB()); +AABB RendererStorageRD::voxel_gi_get_bounds(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, AABB()); - return gi_probe->bounds; + return voxel_gi->bounds; } -Vector3i RendererStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Vector3i()); - return gi_probe->octree_size; +Vector3i RendererStorageRD::voxel_gi_get_octree_size(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector3i()); + return voxel_gi->octree_size; } -Vector<uint8_t> RendererStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); +Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - if (gi_probe->octree_buffer.is_valid()) { - return RD::get_singleton()->buffer_get_data(gi_probe->octree_buffer); + if (voxel_gi->octree_buffer.is_valid()) { + return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer); } return Vector<uint8_t>(); } -Vector<uint8_t> RendererStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); +Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - if (gi_probe->data_buffer.is_valid()) { - return RD::get_singleton()->buffer_get_data(gi_probe->data_buffer); + if (voxel_gi->data_buffer.is_valid()) { + return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer); } return Vector<uint8_t>(); } -Vector<uint8_t> RendererStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); +Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); - if (gi_probe->data_buffer.is_valid()) { - return RD::get_singleton()->texture_get_data(gi_probe->sdf_texture, 0); + if (voxel_gi->data_buffer.is_valid()) { + return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0); } return Vector<uint8_t>(); } -Vector<int> RendererStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Vector<int>()); +Vector<int> RendererStorageRD::voxel_gi_get_level_counts(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Vector<int>()); - return gi_probe->level_counts; + return voxel_gi->level_counts; } -Transform RendererStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, Transform()); +Transform3D RendererStorageRD::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, Transform3D()); - return gi_probe->to_cell_xform; + return voxel_gi->to_cell_xform; } -void RendererStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->dynamic_range = p_range; - gi_probe->version++; + voxel_gi->dynamic_range = p_range; + voxel_gi->version++; } -float RendererStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); +float RendererStorageRD::voxel_gi_get_dynamic_range(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); - return gi_probe->dynamic_range; + return voxel_gi->dynamic_range; } -void RendererStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->propagation = p_range; - gi_probe->version++; + voxel_gi->propagation = p_range; + voxel_gi->version++; } -float RendererStorageRD::gi_probe_get_propagation(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->propagation; +float RendererStorageRD::voxel_gi_get_propagation(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->propagation; } -void RendererStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->energy = p_energy; + voxel_gi->energy = p_energy; } -float RendererStorageRD::gi_probe_get_energy(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->energy; +float RendererStorageRD::voxel_gi_get_energy(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->energy; } -void RendererStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_ao(RID p_voxel_gi, float p_ao) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->ao = p_ao; + voxel_gi->ao = p_ao; } -float RendererStorageRD::gi_probe_get_ao(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->ao; +float RendererStorageRD::voxel_gi_get_ao(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->ao; } -void RendererStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_ao_size(RID p_voxel_gi, float p_strength) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->ao_size = p_strength; + voxel_gi->ao_size = p_strength; } -float RendererStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->ao_size; +float RendererStorageRD::voxel_gi_get_ao_size(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->ao_size; } -void RendererStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->bias = p_bias; + voxel_gi->bias = p_bias; } -float RendererStorageRD::gi_probe_get_bias(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->bias; +float RendererStorageRD::voxel_gi_get_bias(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->bias; } -void RendererStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->normal_bias = p_normal_bias; + voxel_gi->normal_bias = p_normal_bias; } -float RendererStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->normal_bias; +float RendererStorageRD::voxel_gi_get_normal_bias(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->normal_bias; } -void RendererStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->anisotropy_strength = p_strength; + voxel_gi->anisotropy_strength = p_strength; } -float RendererStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->anisotropy_strength; +float RendererStorageRD::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->anisotropy_strength; } -void RendererStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->interior = p_enable; + voxel_gi->interior = p_enable; } -void RendererStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND(!gi_probe); +void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND(!voxel_gi); - gi_probe->use_two_bounces = p_enable; - gi_probe->version++; + voxel_gi->use_two_bounces = p_enable; + voxel_gi->version++; } -bool RendererStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, false); - return gi_probe->use_two_bounces; +bool RendererStorageRD::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, false); + return voxel_gi->use_two_bounces; } -bool RendererStorageRD::gi_probe_is_interior(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->interior; +bool RendererStorageRD::voxel_gi_is_interior(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->interior; } -uint32_t RendererStorageRD::gi_probe_get_version(RID p_gi_probe) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->version; +uint32_t RendererStorageRD::voxel_gi_get_version(RID p_voxel_gi) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->version; } -uint32_t RendererStorageRD::gi_probe_get_data_version(RID p_gi_probe) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, 0); - return gi_probe->data_version; +uint32_t RendererStorageRD::voxel_gi_get_data_version(RID p_voxel_gi) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, 0); + return voxel_gi->data_version; } -RID RendererStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, RID()); - return gi_probe->octree_buffer; +RID RendererStorageRD::voxel_gi_get_octree_buffer(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); + return voxel_gi->octree_buffer; } -RID RendererStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, RID()); - return gi_probe->data_buffer; +RID RendererStorageRD::voxel_gi_get_data_buffer(RID p_voxel_gi) const { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); + return voxel_gi->data_buffer; } -RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); - ERR_FAIL_COND_V(!gi_probe, RID()); +RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) { + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + ERR_FAIL_COND_V(!voxel_gi, RID()); - return gi_probe->sdf_texture; + return voxel_gi->sdf_texture; } /* LIGHTMAP API */ @@ -7566,8 +7566,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_ } else if (decal_owner.owns(p_base)) { Decal *decal = decal_owner.getornull(p_base); p_instance->update_dependency(&decal->dependency); - } else if (gi_probe_owner.owns(p_base)) { - GIProbe *gip = gi_probe_owner.getornull(p_base); + } else if (voxel_gi_owner.owns(p_base)) { + VoxelGI *gip = voxel_gi_owner.getornull(p_base); p_instance->update_dependency(&gip->dependency); } else if (lightmap_owner.owns(p_base)) { Lightmap *lm = lightmap_owner.getornull(p_base); @@ -7604,8 +7604,8 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const { if (decal_owner.owns(p_rid)) { return RS::INSTANCE_DECAL; } - if (gi_probe_owner.owns(p_rid)) { - return RS::INSTANCE_GI_PROBE; + if (voxel_gi_owner.owns(p_rid)) { + return RS::INSTANCE_VOXEL_GI; } if (light_owner.owns(p_rid)) { return RS::INSTANCE_LIGHT; @@ -8129,7 +8129,7 @@ void RendererStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::Gl } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; - Transform v = p_value; + Transform3D v = p_value; bv[0].x = v.basis.elements[0][0]; bv[0].y = v.basis.elements[1][0]; bv[0].z = v.basis.elements[2][0]; @@ -8662,11 +8662,11 @@ bool RendererStorageRD::free(RID p_rid) { } decal->dependency.deleted_notify(p_rid); decal_owner.free(p_rid); - } else if (gi_probe_owner.owns(p_rid)) { - gi_probe_allocate_data(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate - GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); - gi_probe->dependency.deleted_notify(p_rid); - gi_probe_owner.free(p_rid); + } else if (voxel_gi_owner.owns(p_rid)) { + voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate + VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_rid); + voxel_gi->dependency.deleted_notify(p_rid); + voxel_gi_owner.free(p_rid); } else if (lightmap_owner.owns(p_rid)) { lightmap_set_textures(p_rid, RID(), false); Lightmap *lightmap = lightmap_owner.getornull(p_rid); @@ -9181,10 +9181,10 @@ RendererStorageRD::RendererStorageRD() { { Vector<String> sdf_versions; sdf_versions.push_back(""); //one only - giprobe_sdf_shader.initialize(sdf_versions); - giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); - giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); - giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); + voxel_gi_sdf_shader.initialize(sdf_versions); + voxel_gi_sdf_shader_version = voxel_gi_sdf_shader.version_create(); + voxel_gi_sdf_shader_version_shader = voxel_gi_sdf_shader.version_get_shader(voxel_gi_sdf_shader_version, 0); + voxel_gi_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(voxel_gi_sdf_shader_version_shader); } using_lightmap_array = true; // high end @@ -9400,7 +9400,7 @@ RendererStorageRD::~RendererStorageRD() { RD::get_singleton()->free(mesh_default_rd_buffers[i]); } - giprobe_sdf_shader.version_free(giprobe_sdf_shader_version); + voxel_gi_sdf_shader.version_free(voxel_gi_sdf_shader_version); particles_shader.copy_shader.version_free(particles_shader.copy_shader_version); rt_sdf.shader.version_free(rt_sdf.shader_version); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 67fbeb3008..8bfab545fd 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -38,15 +38,15 @@ #include "servers/rendering/renderer_rd/effects_rd.h" #include "servers/rendering/renderer_rd/shader_compiler_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" class RendererStorageRD : public RendererStorage { public: - static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) { p_array[0] = p_mtx.basis.elements[0][0]; p_array[1] = p_mtx.basis.elements[1][0]; p_array[2] = p_mtx.basis.elements[2][0]; @@ -95,7 +95,7 @@ public: p_array[11] = 0; } - static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) { p_array[0] = p_mtx.basis.elements[0][0]; p_array[1] = p_mtx.basis.elements[0][1]; p_array[2] = p_mtx.basis.elements[0][2]; @@ -726,7 +726,7 @@ private: RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX; Vector<RID> draw_passes; - Vector<Transform> trail_bind_poses; + Vector<Transform3D> trail_bind_poses; bool trail_bind_poses_dirty = false; RID trail_bind_pose_buffer; RID trail_bind_pose_uniform_set; @@ -771,7 +771,7 @@ private: bool force_sub_emit = false; - Transform emission_transform; + Transform3D emission_transform; Vector<uint8_t> emission_buffer_data; @@ -941,7 +941,7 @@ private: struct ParticlesCollisionInstance { RID collision; - Transform transform; + Transform3D transform; bool active = false; }; @@ -1045,9 +1045,9 @@ private: mutable RID_Owner<Decal, true> decal_owner; - /* GI PROBE */ + /* VOXEL GI */ - struct GIProbe { + struct VoxelGI { RID octree_buffer; RID data_buffer; RID sdf_texture; @@ -1059,7 +1059,7 @@ private: int cell_count = 0; - Transform to_cell_xform; + Transform3D to_cell_xform; AABB bounds; Vector3i octree_size; @@ -1081,12 +1081,12 @@ private: Dependency dependency; }; - GiprobeSdfShaderRD giprobe_sdf_shader; - RID giprobe_sdf_shader_version; - RID giprobe_sdf_shader_version_shader; - RID giprobe_sdf_shader_pipeline; + VoxelGiSdfShaderRD voxel_gi_sdf_shader; + RID voxel_gi_sdf_shader_version; + RID voxel_gi_sdf_shader_version_shader; + RID voxel_gi_sdf_shader_pipeline; - mutable RID_Owner<GIProbe, true> gi_probe_owner; + mutable RID_Owner<VoxelGI, true> voxel_gi_owner; /* REFLECTION PROBE */ @@ -1661,14 +1661,14 @@ public: int multimesh_get_instance_count(RID p_multimesh) const; void multimesh_set_mesh(RID p_multimesh, RID p_mesh); - void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); + void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform); void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform); void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color); RID multimesh_get_mesh(RID p_multimesh) const; - Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; + Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const; Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const; Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const; @@ -1759,10 +1759,10 @@ public: void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform); - void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform); + void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform3D &p_world_transform); int skeleton_get_bone_count(RID p_skeleton) const; - void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform); - Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const; + void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform); + Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const; void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform); Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; @@ -2019,59 +2019,59 @@ public: virtual AABB decal_get_aabb(RID p_decal) const; - /* GI PROBE API */ + /* VOXEL GI API */ - RID gi_probe_allocate(); - void gi_probe_initialize(RID p_gi_probe); + RID voxel_gi_allocate(); + void voxel_gi_initialize(RID p_voxel_gi); - void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); + void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); - AABB gi_probe_get_bounds(RID p_gi_probe) const; - Vector3i gi_probe_get_octree_size(RID p_gi_probe) const; - Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const; - Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const; - Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const; + AABB voxel_gi_get_bounds(RID p_voxel_gi) const; + Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const; + Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const; + Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const; + Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const; - Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const; - Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const; + Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const; + Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const; - void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range); - float gi_probe_get_dynamic_range(RID p_gi_probe) const; + void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range); + float voxel_gi_get_dynamic_range(RID p_voxel_gi) const; - void gi_probe_set_propagation(RID p_gi_probe, float p_range); - float gi_probe_get_propagation(RID p_gi_probe) const; + void voxel_gi_set_propagation(RID p_voxel_gi, float p_range); + float voxel_gi_get_propagation(RID p_voxel_gi) const; - void gi_probe_set_energy(RID p_gi_probe, float p_energy); - float gi_probe_get_energy(RID p_gi_probe) const; + void voxel_gi_set_energy(RID p_voxel_gi, float p_energy); + float voxel_gi_get_energy(RID p_voxel_gi) const; - void gi_probe_set_ao(RID p_gi_probe, float p_ao); - float gi_probe_get_ao(RID p_gi_probe) const; + void voxel_gi_set_ao(RID p_voxel_gi, float p_ao); + float voxel_gi_get_ao(RID p_voxel_gi) const; - void gi_probe_set_ao_size(RID p_gi_probe, float p_strength); - float gi_probe_get_ao_size(RID p_gi_probe) const; + void voxel_gi_set_ao_size(RID p_voxel_gi, float p_strength); + float voxel_gi_get_ao_size(RID p_voxel_gi) const; - void gi_probe_set_bias(RID p_gi_probe, float p_bias); - float gi_probe_get_bias(RID p_gi_probe) const; + void voxel_gi_set_bias(RID p_voxel_gi, float p_bias); + float voxel_gi_get_bias(RID p_voxel_gi) const; - void gi_probe_set_normal_bias(RID p_gi_probe, float p_range); - float gi_probe_get_normal_bias(RID p_gi_probe) const; + void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range); + float voxel_gi_get_normal_bias(RID p_voxel_gi) const; - void gi_probe_set_interior(RID p_gi_probe, bool p_enable); - bool gi_probe_is_interior(RID p_gi_probe) const; + void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable); + bool voxel_gi_is_interior(RID p_voxel_gi) const; - void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable); - bool gi_probe_is_using_two_bounces(RID p_gi_probe) const; + void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable); + bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const; - void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength); - float gi_probe_get_anisotropy_strength(RID p_gi_probe) const; + void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength); + float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const; - uint32_t gi_probe_get_version(RID p_probe); - uint32_t gi_probe_get_data_version(RID p_probe); + uint32_t voxel_gi_get_version(RID p_probe); + uint32_t voxel_gi_get_data_version(RID p_probe); - RID gi_probe_get_octree_buffer(RID p_gi_probe) const; - RID gi_probe_get_data_buffer(RID p_gi_probe) const; + RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const; + RID voxel_gi_get_data_buffer(RID p_voxel_gi) const; - RID gi_probe_get_sdf_texture(RID p_gi_probe); + RID voxel_gi_get_sdf_texture(RID p_voxel_gi); /* LIGHTMAP CAPTURE */ @@ -2147,10 +2147,10 @@ public: void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align); void particles_set_trails(RID p_particles, bool p_enable, float p_length); - void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses); + void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses); void particles_restart(RID p_particles); - void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); + void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); void particles_set_subemitter(RID p_particles, RID p_subemitter_particles); @@ -2163,7 +2163,7 @@ public: AABB particles_get_current_aabb(RID p_particles); AABB particles_get_aabb(RID p_particles) const; - void particles_set_emission_transform(RID p_particles, const Transform &p_transform); + void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform); bool particles_get_emitting(RID p_particles); int particles_get_draw_passes(RID p_particles) const; @@ -2254,7 +2254,7 @@ public: //used from 2D and 3D virtual RID particles_collision_instance_create(RID p_collision); - virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform); + virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform); virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active); /* GLOBAL VARIABLES API */ diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 7deedb80c3..b347197289 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -1504,7 +1504,6 @@ ShaderCompilerRD::ShaderCompilerRD() { actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; } - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index bfd5c4c88d..3977f4efa0 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -35,7 +35,7 @@ layout(set = 0, binding = 11) uniform texture2DArray lightprobe_texture; layout(set = 0, binding = 12) uniform texture2D depth_buffer; layout(set = 0, binding = 13) uniform texture2D normal_roughness_buffer; -layout(set = 0, binding = 14) uniform utexture2D giprobe_buffer; +layout(set = 0, binding = 14) uniform utexture2D voxel_gi_buffer; layout(set = 0, binding = 15, std140) uniform SDFGI { vec3 grid_size; @@ -65,9 +65,9 @@ layout(set = 0, binding = 15, std140) uniform SDFGI { } sdfgi; -#define MAX_GI_PROBES 8 +#define MAX_VOXEL_GI_INSTANCES 8 -struct GIProbeData { +struct VoxelGIData { mat4 xform; vec3 bounds; float dynamic_range; @@ -83,12 +83,12 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 0, binding = 16, std140) uniform GIProbes { - GIProbeData data[MAX_GI_PROBES]; +layout(set = 0, binding = 16, std140) uniform VoxelGIs { + VoxelGIData data[MAX_VOXEL_GI_INSTANCES]; } -gi_probes; +voxel_gi_instances; -layout(set = 0, binding = 17) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +layout(set = 0, binding = 17) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; layout(push_constant, binding = 0, std430) uniform Params { ivec2 screen_size; @@ -98,7 +98,7 @@ layout(push_constant, binding = 0, std430) uniform Params { vec4 proj_info; vec3 ao_color; - uint max_giprobes; + uint max_voxel_gi_instances; bool high_quality_vct; bool orthogonal; @@ -155,7 +155,7 @@ vec3 reconstruct_position(ivec2 screen_pos) { return pos; } -void sdfgi_probe_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) { +void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) { cascade_pos += cam_normal * sdfgi.normal_bias; vec3 base_pos = floor(cascade_pos); @@ -293,7 +293,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o float blend; vec3 diffuse, specular; - sdfgi_probe_process(cascade, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse, specular); + sdfvoxel_gi_process(cascade, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse, specular); { //process blend @@ -323,7 +323,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o } else { vec3 diffuse2, specular2; cascade_pos = (cam_pos - sdfgi.cascades[cascade + 1].position) * sdfgi.cascades[cascade + 1].to_probe; - sdfgi_probe_process(cascade + 1, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse2, specular2); + sdfvoxel_gi_process(cascade + 1, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse2, specular2); diffuse = mix(diffuse, diffuse2, blend); specular = mix(specular, specular2, blend); } @@ -494,26 +494,26 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 return color; } -void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, inout vec4 out_spec, inout vec4 out_diff, inout float out_blend) { - position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz; - ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz); - normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz); +void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, inout vec4 out_spec, inout vec4 out_diff, inout float out_blend) { + position = (voxel_gi_instances.data[index].xform * vec4(position, 1.0)).xyz; + ref_vec = normalize((voxel_gi_instances.data[index].xform * vec4(ref_vec, 0.0)).xyz); + normal = normalize((voxel_gi_instances.data[index].xform * vec4(normal, 0.0)).xyz); - position += normal * gi_probes.data[index].normal_bias; + position += normal * voxel_gi_instances.data[index].normal_bias; //this causes corrupted pixels, i have no idea why.. - if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, gi_probes.data[index].bounds))))) { + if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, voxel_gi_instances.data[index].bounds))))) { return; } - mat3 dir_xform = mat3(gi_probes.data[index].xform) * normal_xform; + mat3 dir_xform = mat3(voxel_gi_instances.data[index].xform) * normal_xform; - vec3 blendv = abs(position / gi_probes.data[index].bounds * 2.0 - 1.0); + vec3 blendv = abs(position / voxel_gi_instances.data[index].bounds * 2.0 - 1.0); float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0); //float blend=1.0; - float max_distance = length(gi_probes.data[index].bounds); - vec3 cell_size = 1.0 / gi_probes.data[index].bounds; + float max_distance = length(voxel_gi_instances.data[index].bounds); + vec3 cell_size = 1.0 / voxel_gi_instances.data[index].bounds; //irradiance @@ -534,7 +534,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 for (uint i = 0; i < cone_dir_count; i++) { vec3 dir = normalize(dir_xform * cone_dirs[i]); - light += cone_weights[i] * voxel_cone_trace(gi_probe_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias); + light += cone_weights[i] * voxel_cone_trace(voxel_gi_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, voxel_gi_instances.data[index].bias); } } else { const uint cone_dir_count = 4; @@ -547,42 +547,42 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 float cone_weights[cone_dir_count] = float[](0.25, 0.25, 0.25, 0.25); for (int i = 0; i < cone_dir_count; i++) { vec3 dir = normalize(dir_xform * cone_dirs[i]); - light += cone_weights[i] * voxel_cone_trace_45_degrees(gi_probe_textures[index], cell_size, position, dir, max_distance, gi_probes.data[index].bias); + light += cone_weights[i] * voxel_cone_trace_45_degrees(voxel_gi_textures[index], cell_size, position, dir, max_distance, voxel_gi_instances.data[index].bias); } } - if (gi_probes.data[index].ambient_occlusion > 0.001) { - float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0; + if (voxel_gi_instances.data[index].ambient_occlusion > 0.001) { + float size = 1.0 + voxel_gi_instances.data[index].ambient_occlusion_size * 7.0; float taps, blend; blend = modf(size, taps); float ao = 0.0; for (float i = 1.0; i <= taps; i++) { vec3 ofs = (position + normal * (i * 0.5 + 1.0)) * cell_size; - ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, i - 1.0).a * i; + ao += textureLod(sampler3D(voxel_gi_textures[index], linear_sampler_with_mipmaps), ofs, i - 1.0).a * i; } if (blend > 0.001) { vec3 ofs = (position + normal * ((taps + 1.0) * 0.5 + 1.0)) * cell_size; - ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, taps).a * (taps + 1.0) * blend; + ao += textureLod(sampler3D(voxel_gi_textures[index], linear_sampler_with_mipmaps), ofs, taps).a * (taps + 1.0) * blend; } ao = 1.0 - min(1.0, ao); - light.rgb = mix(params.ao_color, light.rgb, mix(1.0, ao, gi_probes.data[index].ambient_occlusion)); + light.rgb = mix(params.ao_color, light.rgb, mix(1.0, ao, voxel_gi_instances.data[index].ambient_occlusion)); } - light.rgb *= gi_probes.data[index].dynamic_range; - if (!gi_probes.data[index].blend_ambient) { + light.rgb *= voxel_gi_instances.data[index].dynamic_range; + if (!voxel_gi_instances.data[index].blend_ambient) { light.a = 1.0; } out_diff += light * blend; //radiance - vec4 irr_light = voxel_cone_trace(gi_probe_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias); - irr_light.rgb *= gi_probes.data[index].dynamic_range; - if (!gi_probes.data[index].blend_ambient) { + vec4 irr_light = voxel_cone_trace(voxel_gi_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, voxel_gi_instances.data[index].bias); + irr_light.rgb *= voxel_gi_instances.data[index].dynamic_range; + if (!voxel_gi_instances.data[index].blend_ambient) { irr_light.a = 1.0; } @@ -614,9 +614,9 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light); #endif -#ifdef USE_GIPROBES +#ifdef USE_VOXEL_GI_INSTANCES { - uvec2 giprobe_tex = texelFetch(usampler2D(giprobe_buffer, linear_sampler), pos, 0).rg; + uvec2 voxel_gi_tex = texelFetch(usampler2D(voxel_gi_buffer, linear_sampler), pos, 0).rg; roughness *= roughness; //find arbitrary tangent and bitangent, then build a matrix vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); @@ -628,9 +628,9 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref vec4 spec_accum = vec4(0.0); float blend_accum = 0.0; - for (uint i = 0; i < params.max_giprobes; i++) { - if (any(equal(uvec2(i), giprobe_tex))) { - gi_probe_compute(i, vertex, normal, reflection, normal_mat, roughness, spec_accum, amb_accum, blend_accum); + for (uint i = 0; i < params.max_voxel_gi_instances; i++) { + if (any(equal(uvec2(i), voxel_gi_tex))) { + voxel_gi_compute(i, vertex, normal, reflection, normal_mat, roughness, spec_accum, amb_accum, blend_accum); } } if (blend_accum > 0.0) { diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index 2286a26485..a4610e081c 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -13,9 +13,9 @@ layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness; layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth; layout(rgba8, set = 1, binding = 1) uniform restrict writeonly image2D dest_normal_roughness; -#ifdef GIPROBE_RESOLVE -layout(set = 2, binding = 0) uniform usampler2DMS source_giprobe; -layout(rg8ui, set = 3, binding = 0) uniform restrict writeonly uimage2D dest_giprobe; +#ifdef VOXEL_GI_RESOLVE +layout(set = 2, binding = 0) uniform usampler2DMS source_voxel_gi; +layout(rg8ui, set = 3, binding = 0) uniform restrict writeonly uimage2D dest_voxel_gi; #endif #endif @@ -38,8 +38,8 @@ void main() { float best_depth = 1e20; vec4 best_normal_roughness = vec4(0.0); -#ifdef GIPROBE_RESOLVE - uvec2 best_giprobe; +#ifdef VOXEL_GI_RESOLVE + uvec2 best_voxel_gi; #endif #if 0 @@ -50,8 +50,8 @@ void main() { best_depth = depth; best_normal_roughness = texelFetch(source_normal_roughness,pos,i); -#ifdef GIPROBE_RESOLVE - best_giprobe = texelFetch(source_giprobe,pos,i).rg; +#ifdef VOXEL_GI_RESOLVE + best_voxel_gi = texelFetch(source_voxel_gi,pos,i).rg; #endif } } @@ -204,16 +204,16 @@ void main() { #endif best_depth = texelFetch(source_depth, pos, best_index).r; best_normal_roughness = texelFetch(source_normal_roughness, pos, best_index); -#ifdef GIPROBE_RESOLVE - best_giprobe = texelFetch(source_giprobe, pos, best_index).rg; +#ifdef VOXEL_GI_RESOLVE + best_voxel_gi = texelFetch(source_voxel_gi, pos, best_index).rg; #endif #endif imageStore(dest_depth, pos, vec4(best_depth)); imageStore(dest_normal_roughness, pos, vec4(best_normal_roughness)); -#ifdef GIPROBE_RESOLVE - imageStore(dest_giprobe, pos, uvec4(best_giprobe, 0, 0)); +#ifdef VOXEL_GI_RESOLVE + imageStore(dest_voxel_gi, pos, uvec4(best_voxel_gi, 0, 0)); #endif #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index e09b8f15be..23f56fd42d 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -426,8 +426,8 @@ layout(location = 4) out float depth_output_buffer; #ifdef MODE_RENDER_NORMAL_ROUGHNESS layout(location = 0) out vec4 normal_roughness_output_buffer; -#ifdef MODE_RENDER_GIPROBE -layout(location = 1) out uvec2 giprobe_buffer; +#ifdef MODE_RENDER_VOXEL_GI +layout(location = 1) out uvec2 voxel_gi_buffer; #endif #endif //MODE_RENDER_NORMAL @@ -1042,7 +1042,7 @@ void main() { } } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); @@ -1054,12 +1054,12 @@ void main() { vec4 amb_accum = vec4(0.0); vec4 spec_accum = vec4(0.0); - gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + voxel_gi_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); uint index2 = instances.data[instance_index].gi_offset >> 16; if (index2 != 0xFFFF) { - gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + voxel_gi_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); } if (amb_accum.a > 0.0) { @@ -1929,15 +1929,15 @@ void main() { #ifdef MODE_RENDER_NORMAL_ROUGHNESS normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); -#ifdef MODE_RENDER_GIPROBE - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes +#ifdef MODE_RENDER_VOXEL_GI + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; uint index2 = instances.data[instance_index].gi_offset >> 16; - giprobe_buffer.x = index1 & 0xFF; - giprobe_buffer.y = index2 & 0xFF; + voxel_gi_buffer.x = index1 & 0xFF; + voxel_gi_buffer.y = index2 & 0xFF; } else { - giprobe_buffer.x = 0xFF; - giprobe_buffer.y = 0xFF; + voxel_gi_buffer.x = 0xFF; + voxel_gi_buffer.y = 0xFF; } #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index ca75d6300e..e64e52623e 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -1,7 +1,7 @@ #define M_PI 3.14159265359 #define ROUGHNESS_MAX_LOD 5 -#define MAX_GI_PROBES 8 +#define MAX_VOXEL_GI_INSTANCES 8 #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) @@ -15,7 +15,7 @@ #include "cluster_data_inc.glsl" #include "decal_data_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) +#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) #ifndef NORMAL_USED #define NORMAL_USED #endif @@ -57,7 +57,7 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) #define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) #define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) @@ -122,7 +122,7 @@ layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableDat } global_variables; -struct SDFGIProbeCascadeData { +struct SDFVoxelGICascadeData { vec3 position; float to_probe; ivec3 probe_world_offset; @@ -153,7 +153,7 @@ layout(set = 0, binding = 13, std140) uniform SDFGI { vec3 cascade_probe_size; uint pad5; - SDFGIProbeCascadeData cascades[SDFGI_MAX_CASCADES]; + SDFVoxelGICascadeData cascades[SDFGI_MAX_CASCADES]; } sdfgi; @@ -275,7 +275,7 @@ layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +layout(set = 1, binding = 7) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer { uint data[]; @@ -306,7 +306,7 @@ layout(set = 1, binding = 14) uniform texture2D reflection_buffer; layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; -struct GIProbeData { +struct VoxelGIData { mat4 xform; vec3 bounds; float dynamic_range; @@ -322,10 +322,10 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 1, binding = 17, std140) uniform GIProbes { - GIProbeData data[MAX_GI_PROBES]; +layout(set = 1, binding = 17, std140) uniform VoxelGIs { + VoxelGIData data[MAX_VOXEL_GI_INSTANCES]; } -gi_probes; +voxel_gi_instances; layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl index b41f16cbe7..c88bd0a14b 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl @@ -48,24 +48,24 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 return color; } -void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) { - position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz; - ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz); - normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz); +void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) { + position = (voxel_gi_instances.data[index].xform * vec4(position, 1.0)).xyz; + ref_vec = normalize((voxel_gi_instances.data[index].xform * vec4(ref_vec, 0.0)).xyz); + normal = normalize((voxel_gi_instances.data[index].xform * vec4(normal, 0.0)).xyz); - position += normal * gi_probes.data[index].normal_bias; + position += normal * voxel_gi_instances.data[index].normal_bias; //this causes corrupted pixels, i have no idea why.. - if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, gi_probes.data[index].bounds))))) { + if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, voxel_gi_instances.data[index].bounds))))) { return; } - vec3 blendv = abs(position / gi_probes.data[index].bounds * 2.0 - 1.0); + vec3 blendv = abs(position / voxel_gi_instances.data[index].bounds * 2.0 - 1.0); float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0); //float blend=1.0; - float max_distance = length(gi_probes.data[index].bounds); - vec3 cell_size = 1.0 / gi_probes.data[index].bounds; + float max_distance = length(voxel_gi_instances.data[index].bounds); + vec3 cell_size = 1.0 / voxel_gi_instances.data[index].bounds; //radiance @@ -83,26 +83,26 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 vec3 light = vec3(0.0); for (int i = 0; i < MAX_CONE_DIRS; i++) { - vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz); + vec3 dir = normalize((voxel_gi_instances.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz); - vec4 cone_light = voxel_cone_trace_45_degrees(gi_probe_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias); + vec4 cone_light = voxel_cone_trace_45_degrees(voxel_gi_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, voxel_gi_instances.data[index].bias); - if (gi_probes.data[index].blend_ambient) { + if (voxel_gi_instances.data[index].blend_ambient) { cone_light.rgb = mix(ambient, cone_light.rgb, min(1.0, cone_light.a / 0.95)); } light += cone_weights[i] * cone_light.rgb; } - light *= gi_probes.data[index].dynamic_range; + light *= voxel_gi_instances.data[index].dynamic_range; out_diff += vec4(light * blend, blend); //irradiance - vec4 irr_light = voxel_cone_trace(gi_probe_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias); - if (gi_probes.data[index].blend_ambient) { + vec4 irr_light = voxel_cone_trace(voxel_gi_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, voxel_gi_instances.data[index].bias); + if (voxel_gi_instances.data[index].blend_ambient) { irr_light.rgb = mix(environment, irr_light.rgb, min(1.0, irr_light.a / 0.95)); } - irr_light.rgb *= gi_probes.data[index].dynamic_range; + irr_light.rgb *= voxel_gi_instances.data[index].dynamic_range; //irr_light=vec3(0.0); out_spec += vec4(irr_light.rgb * blend, blend); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 32a86cb166..709ea45b88 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -144,12 +144,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, float metallic = unpackUnorm4x8(orms).z; if (metallic < 1.0) { float roughness = unpackUnorm4x8(orms).y; - -#if defined(DIFFUSE_OREN_NAYAR) - vec3 diffuse_brdf_NL; -#else float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance -#endif #if defined(DIFFUSE_LAMBERT_WRAP) // energy conserving lambert wrap shader @@ -243,7 +238,11 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #elif defined(SPECULAR_PHONG) vec3 R = normalize(-reflect(L, N)); +#ifdef USE_SOFT_SHADOWS float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); +#else + float cRdotV = clamp(dot(R, V), 0.0, 1.0); +#endif float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index 0156b58574..656a764a89 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -51,7 +51,7 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) #define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) #define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index c793b6ebe1..f2010222e5 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl @@ -72,9 +72,9 @@ layout(rgba16f, set = 0, binding = 9) uniform restrict writeonly image3D dest_ma layout(set = 0, binding = 10) uniform sampler shadow_sampler; -#define MAX_GI_PROBES 8 +#define MAX_VOXEL_GI_INSTANCES 8 -struct GIProbeData { +struct VoxelGIData { mat4 xform; vec3 bounds; float dynamic_range; @@ -90,12 +90,12 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 0, binding = 11, std140) uniform GIProbes { - GIProbeData data[MAX_GI_PROBES]; +layout(set = 0, binding = 11, std140) uniform VoxelGIs { + VoxelGIData data[MAX_VOXEL_GI_INSTANCES]; } -gi_probes; +voxel_gi_instances; -layout(set = 0, binding = 12) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +layout(set = 0, binding = 12) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; layout(set = 0, binding = 13) uniform sampler linear_sampler_with_mipmaps; @@ -104,7 +104,7 @@ layout(set = 0, binding = 13) uniform sampler linear_sampler_with_mipmaps; // SDFGI Integration on set 1 #define SDFGI_MAX_CASCADES 8 -struct SDFGIProbeCascadeData { +struct SDFVoxelGICascadeData { vec3 position; float to_probe; ivec3 probe_world_offset; @@ -135,7 +135,7 @@ layout(set = 1, binding = 0, std140) uniform SDFGI { vec3 cascade_probe_size; uint pad5; - SDFGIProbeCascadeData cascades[SDFGI_MAX_CASCADES]; + SDFVoxelGICascadeData cascades[SDFGI_MAX_CASCADES]; } sdfgi; @@ -162,7 +162,7 @@ layout(set = 0, binding = 14, std140) uniform Params { float detail_spread; float gi_inject; - uint max_gi_probes; + uint max_voxel_gi_instances; uint cluster_type_size; vec2 screen_size; @@ -533,21 +533,21 @@ void main() { vec3 world_pos = mat3(params.cam_rotation) * view_pos; - for (uint i = 0; i < params.max_gi_probes; i++) { - vec3 position = (gi_probes.data[i].xform * vec4(world_pos, 1.0)).xyz; + for (uint i = 0; i < params.max_voxel_gi_instances; i++) { + vec3 position = (voxel_gi_instances.data[i].xform * vec4(world_pos, 1.0)).xyz; //this causes corrupted pixels, i have no idea why.. - if (all(bvec2(all(greaterThanEqual(position, vec3(0.0))), all(lessThan(position, gi_probes.data[i].bounds))))) { - position /= gi_probes.data[i].bounds; + if (all(bvec2(all(greaterThanEqual(position, vec3(0.0))), all(lessThan(position, voxel_gi_instances.data[i].bounds))))) { + position /= voxel_gi_instances.data[i].bounds; vec4 light = vec4(0.0); - for (uint j = 0; j < gi_probes.data[i].mipmaps; j++) { - vec4 slight = textureLod(sampler3D(gi_probe_textures[i], linear_sampler_with_mipmaps), position, float(j)); + for (uint j = 0; j < voxel_gi_instances.data[i].mipmaps; j++) { + vec4 slight = textureLod(sampler3D(voxel_gi_textures[i], linear_sampler_with_mipmaps), position, float(j)); float a = (1.0 - light.a); light += a * slight; } - light.rgb *= gi_probes.data[i].dynamic_range * params.gi_inject; + light.rgb *= voxel_gi_instances.data[i].dynamic_range * params.gi_inject; total_light += light.rgb; } diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl index 49a493cdc7..49a493cdc7 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl diff --git a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl index 7d4d72967a..7d4d72967a 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl diff --git a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl index e20b3f680d..e20b3f680d 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index db1e3d1377..355c092dba 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -42,7 +42,7 @@ public: virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0; - virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0; + virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform) = 0; virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0; virtual void camera_set_environment(RID p_camera, RID p_env) = 0; virtual void camera_set_camera_effects(RID p_camera, RID p_fx) = 0; @@ -70,7 +70,7 @@ public: virtual void instance_set_base(RID p_instance, RID p_base) = 0; virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0; - virtual void instance_set_transform(RID p_instance, const Transform &p_transform) = 0; + virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0; virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0; virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0; virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) = 0; @@ -196,7 +196,7 @@ public: virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; - virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; + virtual void voxel_gi_set_quality(RS::VoxelGIQuality) = 0; virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index fcea8e4ffc..a001aea5f4 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -74,7 +74,7 @@ void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p camera->zfar = p_z_far; } -void RendererSceneCull::camera_set_transform(RID p_camera, const Transform &p_transform) { +void RendererSceneCull::camera_set_transform(RID p_camera, const Transform3D &p_transform) { Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->transform = p_transform.orthonormalized(); @@ -190,26 +190,26 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) { ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture } - } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_VOXEL_GI) && B->base_type == RS::INSTANCE_VOXEL_GI && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - geom->gi_probes.insert(B); + geom->voxel_gi_instances.insert(B); if (A->dynamic_gi) { - gi_probe->dynamic_geometries.insert(A); + voxel_gi->dynamic_geometries.insert(A); } else { - gi_probe->geometries.insert(A); + voxel_gi->geometries.insert(A); } if (A->scenario && A->array_index >= 0) { InstanceData &idata = A->scenario->instance_data[A->array_index]; - idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY; + idata.flags |= InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY; } - } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); - gi_probe->lights.insert(A); + } else if (B->base_type == RS::INSTANCE_VOXEL_GI && A->base_type == RS::INSTANCE_LIGHT) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data); + voxel_gi->lights.insert(A); } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) { InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data); RSG::storage->particles_add_collision(A->base, collision->instance); @@ -281,25 +281,25 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture } - } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); + } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_VOXEL_GI) && B->base_type == RS::INSTANCE_VOXEL_GI && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - geom->gi_probes.erase(B); + geom->voxel_gi_instances.erase(B); if (A->dynamic_gi) { - gi_probe->dynamic_geometries.erase(A); + voxel_gi->dynamic_geometries.erase(A); } else { - gi_probe->geometries.erase(A); + voxel_gi->geometries.erase(A); } if (A->scenario && A->array_index >= 0) { InstanceData &idata = A->scenario->instance_data[A->array_index]; - idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY; + idata.flags |= InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY; } - } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); - gi_probe->lights.erase(A); + } else if (B->base_type == RS::INSTANCE_VOXEL_GI && A->base_type == RS::INSTANCE_LIGHT) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data); + voxel_gi->lights.erase(A); } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) { InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data); RSG::storage->particles_remove_collision(A->base, collision->instance); @@ -494,23 +494,23 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { } scene_render->free(lightmap_data->instance); } break; - case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); + case RS::INSTANCE_VOXEL_GI: { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data); #ifdef DEBUG_ENABLED - if (gi_probe->geometries.size()) { - ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe."); + if (voxel_gi->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from VoxelGI."); } #endif #ifdef DEBUG_ENABLED - if (gi_probe->lights.size()) { - ERR_PRINT("BUG, indexing did not unpair lights from GIProbe."); + if (voxel_gi->lights.size()) { + ERR_PRINT("BUG, indexing did not unpair lights from VoxelGI."); } #endif - if (gi_probe->update_element.in_list()) { - gi_probe_update_list.remove(&gi_probe->update_element); + if (voxel_gi->update_element.in_list()) { + voxel_gi_update_list.remove(&voxel_gi->update_element); } - scene_render->free(gi_probe->probe_instance); + scene_render->free(voxel_gi->probe_instance); } break; case RS::INSTANCE_OCCLUDER: { @@ -602,16 +602,16 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { instance->base_data = lightmap_data; lightmap_data->instance = scene_render->lightmap_instance_create(p_base); } break; - case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData); - instance->base_data = gi_probe; - gi_probe->owner = instance; + case RS::INSTANCE_VOXEL_GI: { + InstanceVoxelGIData *voxel_gi = memnew(InstanceVoxelGIData); + instance->base_data = voxel_gi; + voxel_gi->owner = instance; - if (scenario && !gi_probe->update_element.in_list()) { - gi_probe_update_list.add(&gi_probe->update_element); + if (scenario && !voxel_gi->update_element.in_list()) { + voxel_gi_update_list.add(&voxel_gi->update_element); } - gi_probe->probe_instance = scene_render->gi_probe_instance_create(p_base); + voxel_gi->probe_instance = scene_render->voxel_gi_instance_create(p_base); } break; case RS::INSTANCE_OCCLUDER: { @@ -668,22 +668,22 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { case RS::INSTANCE_PARTICLES_COLLISION: { heightfield_particle_colliders_update_list.erase(instance); } break; - case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); + case RS::INSTANCE_VOXEL_GI: { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data); #ifdef DEBUG_ENABLED - if (gi_probe->geometries.size()) { - ERR_PRINT("BUG, indexing did not unpair geometries from GIProbe."); + if (voxel_gi->geometries.size()) { + ERR_PRINT("BUG, indexing did not unpair geometries from VoxelGI."); } #endif #ifdef DEBUG_ENABLED - if (gi_probe->lights.size()) { - ERR_PRINT("BUG, indexing did not unpair lights from GIProbe."); + if (voxel_gi->lights.size()) { + ERR_PRINT("BUG, indexing did not unpair lights from VoxelGI."); } #endif - if (gi_probe->update_element.in_list()) { - gi_probe_update_list.remove(&gi_probe->update_element); + if (voxel_gi->update_element.in_list()) { + voxel_gi_update_list.remove(&voxel_gi->update_element); } } break; case RS::INSTANCE_OCCLUDER: { @@ -714,10 +714,10 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { light->D = scenario->directional_lights.push_back(instance); } } break; - case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); - if (!gi_probe->update_element.in_list()) { - gi_probe_update_list.add(&gi_probe->update_element); + case RS::INSTANCE_VOXEL_GI: { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data); + if (!voxel_gi->update_element.in_list()) { + voxel_gi_update_list.add(&voxel_gi->update_element); } } break; case RS::INSTANCE_OCCLUDER: { @@ -746,7 +746,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) } } -void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) { +void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D &p_transform) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -1253,10 +1253,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data); scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform); - } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); + } else if (p_instance->base_type == RS::INSTANCE_VOXEL_GI) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(p_instance->base_data); - scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); + scene_render->voxel_gi_instance_set_transform_to_data(voxel_gi->probe_instance, p_instance->transform); } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform); } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { @@ -1371,8 +1371,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { case RS::INSTANCE_LIGHTMAP: { idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id(); } break; - case RS::INSTANCE_GI_PROBE: { - idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance.get_id(); + case RS::INSTANCE_VOXEL_GI: { + idata.instance_data_rid = static_cast<InstanceVoxelGIData *>(p_instance->base_data)->probe_instance.get_id(); } break; default: { } @@ -1425,7 +1425,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { pair.pair_mask |= 1 << RS::INSTANCE_LIGHT; - pair.pair_mask |= 1 << RS::INSTANCE_GI_PROBE; + pair.pair_mask |= 1 << RS::INSTANCE_VOXEL_GI; pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP; if (p_instance->base_type == RS::INSTANCE_PARTICLES) { pair.pair_mask |= 1 << RS::INSTANCE_PARTICLES_COLLISION; @@ -1439,7 +1439,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; if (RSG::storage->light_get_bake_mode(p_instance->base) == RS::LIGHT_BAKE_DYNAMIC) { - pair.pair_mask |= (1 << RS::INSTANCE_GI_PROBE); + pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI); pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES]; } } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) { @@ -1451,7 +1451,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { pair.pair_mask = (1 << RS::INSTANCE_PARTICLES); pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; - } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { + } else if (p_instance->base_type == RS::INSTANCE_VOXEL_GI) { //lights and geometries pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK | (1 << RS::INSTANCE_LIGHT); pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; @@ -1504,7 +1504,7 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0); scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0); scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, nullptr, 0); + scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0); } } @@ -1566,8 +1566,8 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) { new_aabb = RSG::storage->decal_get_aabb(p_instance->base); } break; - case RenderingServer::INSTANCE_GI_PROBE: { - new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base); + case RenderingServer::INSTANCE_VOXEL_GI: { + new_aabb = RSG::storage->voxel_gi_get_bounds(p_instance->base); } break; case RenderingServer::INSTANCE_LIGHTMAP: { @@ -1605,7 +1605,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) continue; //we are inside, ignore exteriors } - Transform to_bounds = lightmap->transform.affine_inverse(); + Transform3D to_bounds = lightmap->transform.affine_inverse(); Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center Vector3 lm_pos = to_bounds.xform(center); @@ -1666,10 +1666,10 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr()); } -void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { +void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); - Transform light_transform = p_instance->transform; + Transform3D light_transform = p_instance->transform; light_transform.orthonormalize(); //scale does not count on lights real_t max_distance = p_cam_projection.get_z_far(); @@ -1745,7 +1745,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in // obtain the light frustum ranges (given endpoints) - Transform transform = light_transform; //discard scale and stabilize light + Transform3D transform = light_transform; //discard scale and stabilize light Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized(); Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized(); @@ -1944,7 +1944,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam)); - Transform ortho_transform; + Transform3D ortho_transform; ortho_transform.basis = transform.basis; ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max; @@ -1961,10 +1961,10 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in } } -bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_lod_threshold) { +bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_lod_threshold) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); - Transform light_transform = p_instance->transform; + Transform3D light_transform = p_instance->transform; light_transform.orthonormalize(); //scale does not count on lights bool animated_material_found = false; @@ -2071,7 +2071,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Vector3(0, -1, 0) }; - Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]); + Transform3D xform = light_transform * Transform3D().looking_at(view_normals[i], view_up[i]); Vector<Plane> planes = cm.get_projection_planes(xform); @@ -2250,16 +2250,16 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_ // We also ignore our camera position, it will have been positioned with a slightly old tracking position. // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo! - Transform world_origin = XRServer::get_singleton()->get_world_origin(); - Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin); + Transform3D world_origin = XRServer::get_singleton()->get_world_origin(); + Transform3D cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin); RID environment = _render_get_environment(p_camera, p_scenario); // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye if (p_eye == XRInterface::EYE_LEFT) { // Center our transform, we assume basis is equal. - Transform mono_transform = cam_transform; - Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin); + Transform3D mono_transform = cam_transform; + Transform3D right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin); mono_transform.origin += right_transform.origin; mono_transform.origin *= 0.5; @@ -2307,7 +2307,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_ combined_matrix.set_frustum(left_near, -left_near, bottom_near, top_near, z_near + z_shift, z_far + z_shift); // and finally move our camera back - Transform apply_z_shift; + Transform3D apply_z_shift; apply_z_shift.origin = Vector3(0.0, 0.0, z_shift); // z negative is forward so this moves it backwards mono_transform *= apply_z_shift; @@ -2341,7 +2341,7 @@ void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cu RID instance_pair_buffer[MAX_INSTANCE_PAIRS]; - Transform inv_cam_transform = cull_data.cam_transform.inverse(); + Transform3D inv_cam_transform = cull_data.cam_transform.inverse(); float z_near = cull_data.camera_matrix->get_z_near(); for (uint64_t i = p_from; i < p_to; i++) { @@ -2384,14 +2384,14 @@ void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cu } else if (base_type == RS::INSTANCE_DECAL) { cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid)); - } else if (base_type == RS::INSTANCE_GI_PROBE) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data); + } else if (base_type == RS::INSTANCE_VOXEL_GI) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(idata.instance->base_data); cull_data.cull->lock.lock(); - if (!gi_probe->update_element.in_list()) { - gi_probe_update_list.add(&gi_probe->update_element); + if (!voxel_gi->update_element.in_list()) { + voxel_gi_update_list.add(&voxel_gi->update_element); } cull_data.cull->lock.unlock(); - cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid)); + cull_result.voxel_gi_instances.push_back(RID::from_uint64(idata.instance_data_rid)); } else if (base_type == RS::INSTANCE_LIGHTMAP) { cull_result.lightmaps.push_back(RID::from_uint64(idata.instance_data_rid)); @@ -2468,20 +2468,20 @@ void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cu idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); } - if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) { + if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; - for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data); + for (Set<Instance *>::Element *E = geom->voxel_gi_instances.front(); E; E = E->next()) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->get()->base_data); - instance_pair_buffer[idx++] = gi_probe->probe_instance; + instance_pair_buffer[idx++] = voxel_gi->probe_instance; if (idx == MAX_INSTANCE_PAIRS) { break; } } - scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); - idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY); + scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); + idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) { @@ -2544,7 +2544,7 @@ void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cu } } -void RendererSceneCull::_render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) { +void RendererSceneCull::_render_scene(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -2726,7 +2726,7 @@ void RendererSceneCull::_render_scene(const Transform &p_cam_transform, const Ca { //compute coverage - Transform cam_xf = p_cam_transform; + Transform3D cam_xf = p_cam_transform; float zn = p_cam_projection.get_z_near(); Plane p(cam_xf.origin + cam_xf.basis.get_axis(2) * -zn, -cam_xf.basis.get_axis(2)); //camera near plane @@ -2864,7 +2864,7 @@ void RendererSceneCull::_render_scene(const Transform &p_cam_transform, const Ca } RENDER_TIMESTAMP("Render Scene "); - scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); + scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.voxel_gi_instances, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); for (uint32_t i = 0; i < max_shadows_used; i++) { render_shadow_data[i].instances.clear(); @@ -2875,7 +2875,7 @@ void RendererSceneCull::_render_scene(const Transform &p_cam_transform, const Ca render_sdfgi_data[i].instances.clear(); } - // virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; + // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { @@ -2911,7 +2911,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, environment = scenario->fallback_environment; } RENDER_TIMESTAMP("Render Empty Scene "); - scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); + scene_render->render_scene(p_render_buffers, Transform3D(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -2961,10 +2961,10 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int CameraMatrix cm; cm.set_perspective(90, 1, 0.01, max_distance); - Transform local_view; + Transform3D local_view; local_view.set_look_at(origin_offset, origin_offset + view_normals[p_step], view_up[p_step]); - Transform xform = p_instance->transform * local_view; + Transform3D xform = p_instance->transform * local_view; RID shadow_atlas; @@ -3033,18 +3033,18 @@ void RendererSceneCull::render_probes() { ref_probe = next; } - /* GI PROBES */ + /* VOXEL GIS */ - SelfList<InstanceGIProbeData> *gi_probe = gi_probe_update_list.first(); + SelfList<InstanceVoxelGIData> *voxel_gi = voxel_gi_update_list.first(); - if (gi_probe) { + if (voxel_gi) { RENDER_TIMESTAMP("Render GI Probes"); } - while (gi_probe) { - SelfList<InstanceGIProbeData> *next = gi_probe->next(); + while (voxel_gi) { + SelfList<InstanceVoxelGIData> *next = voxel_gi->next(); - InstanceGIProbeData *probe = gi_probe->self(); + InstanceVoxelGIData *probe = voxel_gi->self(); //Instance *instance_probe = probe->owner; //check if probe must be setup, but don't do if on the lighting thread @@ -3053,7 +3053,7 @@ void RendererSceneCull::render_probes() { int cache_count = 0; { int light_cache_size = probe->light_cache.size(); - const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr(); + const InstanceVoxelGIData::LightCache *caches = probe->light_cache.ptr(); const RID *instance_caches = probe->light_instances.ptr(); int idx = 0; //must count visible lights @@ -3068,7 +3068,7 @@ void RendererSceneCull::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; + const InstanceVoxelGIData::LightCache *cache = &caches[idx]; if ( instance_caches[idx] != instance_light->instance || @@ -3100,7 +3100,7 @@ void RendererSceneCull::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; + const InstanceVoxelGIData::LightCache *cache = &caches[idx]; if ( instance_caches[idx] != instance_light->instance || @@ -3129,14 +3129,14 @@ void RendererSceneCull::render_probes() { cache_count = idx; } - bool update_lights = scene_render->gi_probe_needs_update(probe->probe_instance); + bool update_lights = scene_render->voxel_gi_needs_update(probe->probe_instance); if (cache_dirty) { probe->light_cache.resize(cache_count); probe->light_instances.resize(cache_count); if (cache_count) { - InstanceGIProbeData::LightCache *caches = probe->light_cache.ptrw(); + InstanceVoxelGIData::LightCache *caches = probe->light_cache.ptrw(); RID *instance_caches = probe->light_instances.ptrw(); int idx = 0; //must count visible lights @@ -3147,7 +3147,7 @@ void RendererSceneCull::render_probes() { continue; } - InstanceGIProbeData::LightCache *cache = &caches[idx]; + InstanceVoxelGIData::LightCache *cache = &caches[idx]; instance_caches[idx] = instance_light->instance; cache->has_shadow = RSG::storage->light_has_shadow(instance->base); @@ -3170,7 +3170,7 @@ void RendererSceneCull::render_probes() { continue; } - InstanceGIProbeData::LightCache *cache = &caches[idx]; + InstanceVoxelGIData::LightCache *cache = &caches[idx]; instance_caches[idx] = instance_light->instance; cache->has_shadow = RSG::storage->light_has_shadow(instance->base); @@ -3203,30 +3203,30 @@ void RendererSceneCull::render_probes() { } InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data; - if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY)) { + if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY)) { uint32_t idx = 0; - for (Set<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) { - InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data); + for (Set<Instance *>::Element *F = geom->voxel_gi_instances.front(); F; F = F->next()) { + InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->get()->base_data); - instance_pair_buffer[idx++] = gi_probe2->probe_instance; + instance_pair_buffer[idx++] = voxel_gi2->probe_instance; if (idx == MAX_INSTANCE_PAIRS) { break; } } - scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); - ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY); + ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } frustum_cull_result.geometry_instances.push_back(geom->geometry_instance); } - scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances); + scene_render->voxel_gi_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances); - gi_probe_update_list.remove(gi_probe); + voxel_gi_update_list.remove(voxel_gi); - gi_probe = next; + voxel_gi = next; } } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 930ac0df70..f10eb67828 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -82,7 +82,7 @@ public: RID env; RID effects; - Transform transform; + Transform3D transform; Camera() { visible_layers = 0xFFFFFFFF; @@ -104,7 +104,7 @@ public: virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); - virtual void camera_set_transform(RID p_camera, const Transform &p_transform); + virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform); virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers); virtual void camera_set_environment(RID p_camera, RID p_env); virtual void camera_set_camera_effects(RID p_camera, RID p_fx); @@ -253,7 +253,7 @@ public: FLAG_GEOM_LIGHTING_DIRTY = (1 << 11), FLAG_GEOM_REFLECTION_DIRTY = (1 << 12), FLAG_GEOM_DECAL_DIRTY = (1 << 13), - FLAG_GEOM_GI_PROBE_DIRTY = (1 << 14), + FLAG_GEOM_VOXEL_GI_DIRTY = (1 << 14), FLAG_LIGHTMAP_CAPTURE = (1 << 15), FLAG_USES_BAKED_LIGHT = (1 << 16), FLAG_USES_MESH_INSTANCE = (1 << 17), @@ -353,7 +353,7 @@ public: RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist - Transform transform; + Transform3D transform; float lod_bias; @@ -535,7 +535,7 @@ public: Set<Instance *> decals; Set<Instance *> reflection_probes; - Set<Instance *> gi_probes; + Set<Instance *> voxel_gi_instances; Set<Instance *> lightmap_captures; InstanceGeometryData() { @@ -599,7 +599,7 @@ public: } }; - struct InstanceGIProbeData : public InstanceBaseData { + struct InstanceVoxelGIData : public InstanceBaseData { Instance *owner; Set<Instance *> geometries; @@ -609,7 +609,7 @@ public: struct LightCache { RS::LightType type; - Transform transform; + Transform3D transform; Color color; float energy; float bake_energy; @@ -629,16 +629,16 @@ public: bool invalid; uint32_t base_version; - SelfList<InstanceGIProbeData> update_element; + SelfList<InstanceVoxelGIData> update_element; - InstanceGIProbeData() : + InstanceVoxelGIData() : update_element(this) { invalid = true; base_version = 0; } }; - SelfList<InstanceGIProbeData>::List gi_probe_update_list; + SelfList<InstanceVoxelGIData>::List voxel_gi_update_list; struct InstanceLightmapData : public InstanceBaseData { RID instance; @@ -724,7 +724,7 @@ public: PagedArray<RID> lightmaps; PagedArray<RID> reflections; PagedArray<RID> decals; - PagedArray<RID> gi_probes; + PagedArray<RID> voxel_gi_instances; PagedArray<RID> mesh_instances; struct DirectionalShadow { @@ -741,7 +741,7 @@ public: lightmaps.clear(); reflections.clear(); decals.clear(); - gi_probes.clear(); + voxel_gi_instances.clear(); mesh_instances.clear(); for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { @@ -765,7 +765,7 @@ public: lightmaps.reset(); reflections.reset(); decals.reset(); - gi_probes.reset(); + voxel_gi_instances.reset(); mesh_instances.reset(); for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { @@ -789,7 +789,7 @@ public: lightmaps.merge_unordered(p_cull_result.lightmaps); reflections.merge_unordered(p_cull_result.reflections); decals.merge_unordered(p_cull_result.decals); - gi_probes.merge_unordered(p_cull_result.gi_probes); + voxel_gi_instances.merge_unordered(p_cull_result.voxel_gi_instances); mesh_instances.merge_unordered(p_cull_result.mesh_instances); for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { @@ -814,7 +814,7 @@ public: lightmaps.set_page_pool(p_rid_pool); reflections.set_page_pool(p_rid_pool); decals.set_page_pool(p_rid_pool); - gi_probes.set_page_pool(p_rid_pool); + voxel_gi_instances.set_page_pool(p_rid_pool); mesh_instances.set_page_pool(p_rid_pool); for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { @@ -853,7 +853,7 @@ public: virtual void instance_set_base(RID p_instance, RID p_base); virtual void instance_set_scenario(RID p_instance, RID p_scenario); virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask); - virtual void instance_set_transform(RID p_instance, const Transform &p_transform); + virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform); virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id); virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight); virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material); @@ -893,9 +893,9 @@ public: _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); void _unpair_instance(Instance *p_instance); - void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); + void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); - _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold); + _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold); RID _render_get_environment(RID p_camera, RID p_scenario); @@ -906,7 +906,7 @@ public: Frustum frustum; CameraMatrix projection; - Transform transform; + Transform3D transform; real_t zfar; real_t split; real_t shadow_texel_size; @@ -941,7 +941,7 @@ public: Cull *cull; Scenario *scenario; RID shadow_atlas; - Transform cam_transform; + Transform3D cam_transform; uint32_t visible_layers; Instance *render_reflection_probe; const RendererSceneOcclusionCull::HZBuffer *occlusion_buffer; @@ -952,7 +952,7 @@ public: void _frustum_cull(CullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); + void _render_scene(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas); @@ -975,7 +975,7 @@ public: #define PASSBASE scene_render PASS2(directional_shadow_atlas_set_size, int, bool) - PASS1(gi_probe_set_quality, RS::GIProbeQuality) + PASS1(voxel_gi_set_quality, RS::VoxelGIQuality) /* SKY API */ diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 390bbaa64b..1d0f53c0bf 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -60,7 +60,7 @@ public: void update_mips(); - _FORCE_INLINE_ bool is_occluded(const float p_bounds[6], const Vector3 &p_cam_position, const Transform &p_cam_inv_transform, const CameraMatrix &p_cam_projection, float p_near) const { + _FORCE_INLINE_ bool is_occluded(const float p_bounds[6], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const CameraMatrix &p_cam_projection, float p_near) const { if (is_empty()) { return false; } @@ -171,7 +171,7 @@ public: virtual void add_scenario(RID p_scenario) {} virtual void remove_scenario(RID p_scenario) {} - virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform &p_xform, bool p_enabled) { _print_warining(); } + virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { _print_warining(); } virtual void scenario_remove_instance(RID p_scenario, RID p_instance) { _print_warining(); } virtual void add_buffer(RID p_buffer) { _print_warining(); } @@ -181,7 +181,7 @@ public: } virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warining(); } virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warining(); } - virtual void buffer_update(RID p_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} virtual RID buffer_get_debug_texture(RID p_buffer) { _print_warining(); return RID(); diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 3f28fac549..5f3e6df4e3 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -51,7 +51,7 @@ public: virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0; virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0; virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0; + virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0; virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0; virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0; virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0; @@ -65,7 +65,7 @@ public: virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0; virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; - virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0; + virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0; @@ -161,9 +161,9 @@ public: virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; virtual RID light_instance_create(RID p_light) = 0; - virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; + virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; virtual bool light_instances_can_render_shadow_cube() const { return true; @@ -174,7 +174,7 @@ public: virtual int reflection_atlas_get_size(RID p_ref_atlas) const = 0; virtual RID reflection_probe_instance_create(RID p_probe) = 0; - virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0; + virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0; virtual void reflection_probe_release_atlas_index(RID p_instance) = 0; virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0; virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0; @@ -182,17 +182,17 @@ public: virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0; virtual RID decal_instance_create(RID p_decal) = 0; - virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0; + virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) = 0; virtual RID lightmap_instance_create(RID p_lightmap) = 0; - virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0; + virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) = 0; - virtual RID gi_probe_instance_create(RID p_gi_probe) = 0; - virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0; - virtual bool gi_probe_needs_update(RID p_probe) const = 0; - virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0; + virtual RID voxel_gi_instance_create(RID p_voxel_gi) = 0; + virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) = 0; + virtual bool voxel_gi_needs_update(RID p_probe) const = 0; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0; - virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; + virtual void voxel_gi_set_quality(RS::VoxelGIQuality) = 0; struct RenderShadowData { RID light; @@ -216,10 +216,10 @@ public: uint32_t positional_light_count; }; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0; + virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0; - virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; virtual void set_time(double p_time, double p_step) = 0; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 75975e909d..0b9b82cba0 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -268,14 +268,14 @@ public: virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; - virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0; + virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) = 0; virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0; virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0; virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; - virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; + virtual Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0; virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; @@ -313,8 +313,8 @@ public: virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; - virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; - virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; + virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) = 0; + virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; @@ -413,53 +413,53 @@ public: virtual AABB decal_get_aabb(RID p_decal) const = 0; - /* GI PROBE API */ + /* VOXEL GI API */ - virtual RID gi_probe_allocate() = 0; - virtual void gi_probe_initialize(RID p_rid) = 0; + virtual RID voxel_gi_allocate() = 0; + virtual void voxel_gi_initialize(RID p_rid) = 0; - virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; - virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; - virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0; + virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const = 0; + virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const = 0; - virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0; - virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0; + virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const = 0; + virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_propagation(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0; - virtual float gi_probe_get_energy(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) = 0; + virtual float voxel_gi_get_energy(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0; - virtual float gi_probe_get_ao(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_ao(RID p_voxel_gi, float p_ao) = 0; + virtual float voxel_gi_get_ao(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_ao_size(RID p_voxel_gi, float p_strength) = 0; + virtual float voxel_gi_get_ao_size(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0; - virtual float gi_probe_get_bias(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) = 0; + virtual float voxel_gi_get_bias(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) = 0; + virtual bool voxel_gi_is_interior(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) = 0; + virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) = 0; + virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const = 0; - virtual uint32_t gi_probe_get_version(RID p_probe) = 0; + virtual uint32_t voxel_gi_get_version(RID p_probe) = 0; /* LIGHTMAP */ @@ -507,10 +507,10 @@ public: virtual void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) = 0; virtual void particles_set_trails(RID p_particles, bool p_enable, float p_length) = 0; - virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses) = 0; + virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) = 0; virtual void particles_restart(RID p_particles) = 0; - virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; + virtual void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0; virtual bool particles_is_inactive(RID p_particles) const = 0; @@ -524,7 +524,7 @@ public: virtual AABB particles_get_current_aabb(RID p_particles) = 0; virtual AABB particles_get_aabb(RID p_particles) const = 0; - virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; + virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; virtual int particles_get_draw_passes(RID p_particles) const = 0; virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0; @@ -559,7 +559,7 @@ public: //used from 2D and 3D virtual RID particles_collision_instance_create(RID p_collision) = 0; - virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0; + virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) = 0; virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0; /* GLOBAL VARIABLES */ diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index c6fe6a07e0..cd66cd0716 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -358,7 +358,7 @@ void RenderingServerDefault::_thread_loop() { draw_thread_up.set(); while (!exit.is_set()) { // flush commands one by one, until exit is requested - command_queue.wait_and_flush_one(); + command_queue.wait_and_flush(); } command_queue.flush_all(); // flush all diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index bf47d497b6..6476d7c75d 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -314,7 +314,7 @@ public: FUNC1RC(int, multimesh_get_instance_count, RID) FUNC2(multimesh_set_mesh, RID, RID) - FUNC3(multimesh_instance_set_transform, RID, int, const Transform &) + FUNC3(multimesh_instance_set_transform, RID, int, const Transform3D &) FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) FUNC3(multimesh_instance_set_color, RID, int, const Color &) FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &) @@ -322,7 +322,7 @@ public: FUNC1RC(RID, multimesh_get_mesh, RID) FUNC1RC(AABB, multimesh_get_aabb, RID) - FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) + FUNC2RC(Transform3D, multimesh_instance_get_transform, RID, int) FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) FUNC2RC(Color, multimesh_instance_get_color, RID, int) FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) @@ -353,8 +353,8 @@ public: FUNCRIDSPLIT(skeleton) FUNC3(skeleton_allocate_data, RID, int, bool) FUNC1RC(int, skeleton_get_bone_count, RID) - FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) - FUNC2RC(Transform, skeleton_bone_get_transform, RID, int) + FUNC3(skeleton_bone_set_transform, RID, int, const Transform3D &) + FUNC2RC(Transform3D, skeleton_bone_get_transform, RID, int) FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) @@ -418,47 +418,47 @@ public: /* BAKED LIGHT API */ - FUNCRIDSPLIT(gi_probe) + FUNCRIDSPLIT(voxel_gi) - FUNC8(gi_probe_allocate_data, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) + FUNC8(voxel_gi_allocate_data, RID, const Transform3D &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) - FUNC1RC(AABB, gi_probe_get_bounds, RID) - FUNC1RC(Vector3i, gi_probe_get_octree_size, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) - FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID) - FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID) + FUNC1RC(AABB, voxel_gi_get_bounds, RID) + FUNC1RC(Vector3i, voxel_gi_get_octree_size, RID) + FUNC1RC(Vector<uint8_t>, voxel_gi_get_octree_cells, RID) + FUNC1RC(Vector<uint8_t>, voxel_gi_get_data_cells, RID) + FUNC1RC(Vector<uint8_t>, voxel_gi_get_distance_field, RID) + FUNC1RC(Vector<int>, voxel_gi_get_level_counts, RID) + FUNC1RC(Transform3D, voxel_gi_get_to_cell_xform, RID) - FUNC2(gi_probe_set_dynamic_range, RID, float) - FUNC1RC(float, gi_probe_get_dynamic_range, RID) + FUNC2(voxel_gi_set_dynamic_range, RID, float) + FUNC1RC(float, voxel_gi_get_dynamic_range, RID) - FUNC2(gi_probe_set_propagation, RID, float) - FUNC1RC(float, gi_probe_get_propagation, RID) + FUNC2(voxel_gi_set_propagation, RID, float) + FUNC1RC(float, voxel_gi_get_propagation, RID) - FUNC2(gi_probe_set_energy, RID, float) - FUNC1RC(float, gi_probe_get_energy, RID) + FUNC2(voxel_gi_set_energy, RID, float) + FUNC1RC(float, voxel_gi_get_energy, RID) - FUNC2(gi_probe_set_ao, RID, float) - FUNC1RC(float, gi_probe_get_ao, RID) + FUNC2(voxel_gi_set_ao, RID, float) + FUNC1RC(float, voxel_gi_get_ao, RID) - FUNC2(gi_probe_set_ao_size, RID, float) - FUNC1RC(float, gi_probe_get_ao_size, RID) + FUNC2(voxel_gi_set_ao_size, RID, float) + FUNC1RC(float, voxel_gi_get_ao_size, RID) - FUNC2(gi_probe_set_bias, RID, float) - FUNC1RC(float, gi_probe_get_bias, RID) + FUNC2(voxel_gi_set_bias, RID, float) + FUNC1RC(float, voxel_gi_get_bias, RID) - FUNC2(gi_probe_set_normal_bias, RID, float) - FUNC1RC(float, gi_probe_get_normal_bias, RID) + FUNC2(voxel_gi_set_normal_bias, RID, float) + FUNC1RC(float, voxel_gi_get_normal_bias, RID) - FUNC2(gi_probe_set_interior, RID, bool) - FUNC1RC(bool, gi_probe_is_interior, RID) + FUNC2(voxel_gi_set_interior, RID, bool) + FUNC1RC(bool, voxel_gi_is_interior, RID) - FUNC2(gi_probe_set_use_two_bounces, RID, bool) - FUNC1RC(bool, gi_probe_is_using_two_bounces, RID) + FUNC2(voxel_gi_set_use_two_bounces, RID, bool) + FUNC1RC(bool, voxel_gi_is_using_two_bounces, RID) - FUNC2(gi_probe_set_anisotropy_strength, RID, float) - FUNC1RC(float, gi_probe_get_anisotropy_strength, RID) + FUNC2(voxel_gi_set_anisotropy_strength, RID, float) + FUNC1RC(float, voxel_gi_get_anisotropy_strength, RID) /* LIGHTMAP */ @@ -496,11 +496,11 @@ public: FUNC2(particles_set_fractional_delta, RID, bool) FUNC1R(bool, particles_is_inactive, RID) FUNC3(particles_set_trails, RID, bool, float) - FUNC2(particles_set_trail_bind_poses, RID, const Vector<Transform> &) + FUNC2(particles_set_trail_bind_poses, RID, const Vector<Transform3D> &) FUNC1(particles_request_process, RID) FUNC1(particles_restart, RID) - FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) + FUNC6(particles_emit, RID, const Transform3D &, const Vector3 &, const Color &, const Color &, uint32_t) FUNC2(particles_set_subemitter, RID, RID) FUNC2(particles_set_collision_base_size, RID, float) @@ -512,7 +512,7 @@ public: FUNC3(particles_set_draw_pass_mesh, RID, int, RID) FUNC1R(AABB, particles_get_current_aabb, RID) - FUNC2(particles_set_emission_transform, RID, const Transform &) + FUNC2(particles_set_emission_transform, RID, const Transform3D &) /* PARTICLES COLLISION */ @@ -541,7 +541,7 @@ public: FUNC4(camera_set_perspective, RID, float, float, float) FUNC4(camera_set_orthogonal, RID, float, float, float) FUNC5(camera_set_frustum, RID, float, Vector2, float, float) - FUNC2(camera_set_transform, RID, const Transform &) + FUNC2(camera_set_transform, RID, const Transform3D &) FUNC2(camera_set_cull_mask, RID, uint32_t) FUNC2(camera_set_environment, RID, RID) FUNC2(camera_set_camera_effects, RID, RID) @@ -624,7 +624,7 @@ public: #define server_name RSG::scene FUNC2(directional_shadow_atlas_set_size, int, bool) - FUNC1(gi_probe_set_quality, GIProbeQuality) + FUNC1(voxel_gi_set_quality, VoxelGIQuality) /* SKY API */ @@ -714,7 +714,7 @@ public: FUNC2(instance_set_base, RID, RID) FUNC2(instance_set_scenario, RID, RID) FUNC2(instance_set_layer_mask, RID, uint32_t) - FUNC2(instance_set_transform, RID, const Transform &) + FUNC2(instance_set_transform, RID, const Transform3D &) FUNC2(instance_attach_object_instance_id, RID, ObjectID) FUNC3(instance_set_blend_shape_weight, RID, int, float) FUNC3(instance_set_surface_override_material, RID, int, RID) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 14b21e1f42..8ed774f8e7 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -2941,7 +2941,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C p[2][0] = p_value[8].real; p[2][1] = p_value[9].real; p[2][2] = p_value[10].real; - Transform t = Transform(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real)); + Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real)); value = Variant(t); break; } @@ -3040,7 +3040,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform pi.type = Variant::BASIS; break; case ShaderLanguage::TYPE_MAT4: - pi.type = Variant::TRANSFORM; + pi.type = Variant::TRANSFORM3D; break; case ShaderLanguage::TYPE_SAMPLER2D: case ShaderLanguage::TYPE_ISAMPLER2D: @@ -6375,13 +6375,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } pass_array = false; - bool array_size_incorrect = false; - - if (b->parent_function->return_array_size > 0 && b->parent_function->return_array_size != expr->get_array_size()) { - array_size_incorrect = true; - } - - if (b->parent_function->return_type != expr->get_datatype() || array_size_incorrect || return_struct_name != expr->get_datatype_name()) { + if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) { _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); return ERR_PARSE_ERROR; } diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index a1e892498b..35f1b05796 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -204,7 +204,6 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_lambert"); shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_lambert_wrap"); - shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_oren_nayar"); shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_burley"); shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_toon"); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 4741e90a81..0471990ed7 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1569,32 +1569,32 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("reflection_probe_set_cull_mask", "probe", "layers"), &RenderingServer::reflection_probe_set_cull_mask); #ifndef _MSC_VER -#warning TODO all giprobe methods need re-binding +#warning TODO all voxel_gi methods need re-binding #endif #if 0 - ClassDB::bind_method(D_METHOD("gi_probe_create"), &RenderingServer::gi_probe_create); - ClassDB::bind_method(D_METHOD("gi_probe_set_bounds", "probe", "bounds"), &RenderingServer::gi_probe_set_bounds); - ClassDB::bind_method(D_METHOD("gi_probe_get_bounds", "probe"), &RenderingServer::gi_probe_get_bounds); - ClassDB::bind_method(D_METHOD("gi_probe_set_cell_size", "probe", "range"), &RenderingServer::gi_probe_set_cell_size); - ClassDB::bind_method(D_METHOD("gi_probe_get_cell_size", "probe"), &RenderingServer::gi_probe_get_cell_size); - ClassDB::bind_method(D_METHOD("gi_probe_set_to_cell_xform", "probe", "xform"), &RenderingServer::gi_probe_set_to_cell_xform); - ClassDB::bind_method(D_METHOD("gi_probe_get_to_cell_xform", "probe"), &RenderingServer::gi_probe_get_to_cell_xform); - ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_data", "probe", "data"), &RenderingServer::gi_probe_set_dynamic_data); - ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_data", "probe"), &RenderingServer::gi_probe_get_dynamic_data); - ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_range", "probe", "range"), &RenderingServer::gi_probe_set_dynamic_range); - ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_range", "probe"), &RenderingServer::gi_probe_get_dynamic_range); - ClassDB::bind_method(D_METHOD("gi_probe_set_energy", "probe", "energy"), &RenderingServer::gi_probe_set_energy); - ClassDB::bind_method(D_METHOD("gi_probe_get_energy", "probe"), &RenderingServer::gi_probe_get_energy); - ClassDB::bind_method(D_METHOD("gi_probe_set_bias", "probe", "bias"), &RenderingServer::gi_probe_set_bias); - ClassDB::bind_method(D_METHOD("gi_probe_get_bias", "probe"), &RenderingServer::gi_probe_get_bias); - ClassDB::bind_method(D_METHOD("gi_probe_set_normal_bias", "probe", "bias"), &RenderingServer::gi_probe_set_normal_bias); - ClassDB::bind_method(D_METHOD("gi_probe_get_normal_bias", "probe"), &RenderingServer::gi_probe_get_normal_bias); - ClassDB::bind_method(D_METHOD("gi_probe_set_propagation", "probe", "propagation"), &RenderingServer::gi_probe_set_propagation); - ClassDB::bind_method(D_METHOD("gi_probe_get_propagation", "probe"), &RenderingServer::gi_probe_get_propagation); - ClassDB::bind_method(D_METHOD("gi_probe_set_interior", "probe", "enable"), &RenderingServer::gi_probe_set_interior); - ClassDB::bind_method(D_METHOD("gi_probe_is_interior", "probe"), &RenderingServer::gi_probe_is_interior); - ClassDB::bind_method(D_METHOD("gi_probe_set_compress", "probe", "enable"), &RenderingServer::gi_probe_set_compress); - ClassDB::bind_method(D_METHOD("gi_probe_is_compressed", "probe"), &RenderingServer::gi_probe_is_compressed); + ClassDB::bind_method(D_METHOD("voxel_gi_create"), &RenderingServer::voxel_gi_create); + ClassDB::bind_method(D_METHOD("voxel_gi_set_bounds", "probe", "bounds"), &RenderingServer::voxel_gi_set_bounds); + ClassDB::bind_method(D_METHOD("voxel_gi_get_bounds", "probe"), &RenderingServer::voxel_gi_get_bounds); + ClassDB::bind_method(D_METHOD("voxel_gi_set_cell_size", "probe", "range"), &RenderingServer::voxel_gi_set_cell_size); + ClassDB::bind_method(D_METHOD("voxel_gi_get_cell_size", "probe"), &RenderingServer::voxel_gi_get_cell_size); + ClassDB::bind_method(D_METHOD("voxel_gi_set_to_cell_xform", "probe", "xform"), &RenderingServer::voxel_gi_set_to_cell_xform); + ClassDB::bind_method(D_METHOD("voxel_gi_get_to_cell_xform", "probe"), &RenderingServer::voxel_gi_get_to_cell_xform); + ClassDB::bind_method(D_METHOD("voxel_gi_set_dynamic_data", "probe", "data"), &RenderingServer::voxel_gi_set_dynamic_data); + ClassDB::bind_method(D_METHOD("voxel_gi_get_dynamic_data", "probe"), &RenderingServer::voxel_gi_get_dynamic_data); + ClassDB::bind_method(D_METHOD("voxel_gi_set_dynamic_range", "probe", "range"), &RenderingServer::voxel_gi_set_dynamic_range); + ClassDB::bind_method(D_METHOD("voxel_gi_get_dynamic_range", "probe"), &RenderingServer::voxel_gi_get_dynamic_range); + ClassDB::bind_method(D_METHOD("voxel_gi_set_energy", "probe", "energy"), &RenderingServer::voxel_gi_set_energy); + ClassDB::bind_method(D_METHOD("voxel_gi_get_energy", "probe"), &RenderingServer::voxel_gi_get_energy); + ClassDB::bind_method(D_METHOD("voxel_gi_set_bias", "probe", "bias"), &RenderingServer::voxel_gi_set_bias); + ClassDB::bind_method(D_METHOD("voxel_gi_get_bias", "probe"), &RenderingServer::voxel_gi_get_bias); + ClassDB::bind_method(D_METHOD("voxel_gi_set_normal_bias", "probe", "bias"), &RenderingServer::voxel_gi_set_normal_bias); + ClassDB::bind_method(D_METHOD("voxel_gi_get_normal_bias", "probe"), &RenderingServer::voxel_gi_get_normal_bias); + ClassDB::bind_method(D_METHOD("voxel_gi_set_propagation", "probe", "propagation"), &RenderingServer::voxel_gi_set_propagation); + ClassDB::bind_method(D_METHOD("voxel_gi_get_propagation", "probe"), &RenderingServer::voxel_gi_get_propagation); + ClassDB::bind_method(D_METHOD("voxel_gi_set_interior", "probe", "enable"), &RenderingServer::voxel_gi_set_interior); + ClassDB::bind_method(D_METHOD("voxel_gi_is_interior", "probe"), &RenderingServer::voxel_gi_is_interior); + ClassDB::bind_method(D_METHOD("voxel_gi_set_compress", "probe", "enable"), &RenderingServer::voxel_gi_set_compress); + ClassDB::bind_method(D_METHOD("voxel_gi_is_compressed", "probe"), &RenderingServer::voxel_gi_is_compressed); #endif /* ClassDB::bind_method(D_METHOD("lightmap_create()"), &RenderingServer::lightmap_capture_create); @@ -2022,9 +2022,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OVERDRAW); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_WIREFRAME); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER); - BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO); - BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING); - BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE); @@ -2117,7 +2117,7 @@ void RenderingServer::_bind_methods() { 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_VOXEL_GI); BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP); BIND_ENUM_CONSTANT(INSTANCE_OCCLUDER); BIND_ENUM_CONSTANT(INSTANCE_MAX); @@ -2324,9 +2324,9 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); - GLOBAL_DEF("rendering/global_illumination/gi_probes/anisotropic", false); - GLOBAL_DEF("rendering/global_illumination/gi_probes/quality", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)")); + GLOBAL_DEF("rendering/global_illumination/voxel_gi/anisotropic", false); + GLOBAL_DEF("rendering/global_illumination/voxel_gi/quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/voxel_gi/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/voxel_gi/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)")); GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false); GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index a9ab4928c4..3247717e98 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -371,7 +371,7 @@ public: virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; - virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) = 0; + virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) = 0; virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) = 0; virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) = 0; @@ -379,7 +379,7 @@ public: virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; - virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; + virtual Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0; virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0; @@ -411,8 +411,8 @@ public: virtual RID skeleton_create() = 0; virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; - virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; - virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; + virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) = 0; + virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0; virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0; virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0; @@ -548,56 +548,56 @@ public: virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0; virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; - /* GI PROBE API */ + /* VOXEL GI API */ - virtual RID gi_probe_create() = 0; + virtual RID voxel_gi_create() = 0; - virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; - virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; - virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const = 0; - virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const = 0; - virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const = 0; - virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const = 0; + virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const = 0; + virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const = 0; + virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const = 0; + virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const = 0; + virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_propagation(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_propagation(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_energy(RID p_gi_probe, float p_energy) = 0; - virtual float gi_probe_get_energy(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) = 0; + virtual float voxel_gi_get_energy(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) = 0; - virtual float gi_probe_get_ao(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_ao(RID p_voxel_gi, float p_ao) = 0; + virtual float voxel_gi_get_ao(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_ao_size(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_ao_size(RID p_voxel_gi, float p_strength) = 0; + virtual float voxel_gi_get_ao_size(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_bias(RID p_gi_probe, float p_bias) = 0; - virtual float gi_probe_get_bias(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) = 0; + virtual float voxel_gi_get_bias(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) = 0; - virtual float gi_probe_get_normal_bias(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) = 0; + virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_interior(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_interior(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) = 0; + virtual bool voxel_gi_is_interior(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) = 0; - virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) = 0; + virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const = 0; - virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0; - virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0; + virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) = 0; + virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const = 0; - enum GIProbeQuality { - GI_PROBE_QUALITY_LOW, - GI_PROBE_QUALITY_HIGH, + enum VoxelGIQuality { + VOXEL_GI_QUALITY_LOW, + VOXEL_GI_QUALITY_HIGH, }; - virtual void gi_probe_set_quality(GIProbeQuality) = 0; + virtual void voxel_gi_set_quality(VoxelGIQuality) = 0; /* LIGHTMAP */ @@ -651,7 +651,7 @@ public: virtual void particles_set_transform_align(RID p_particles, ParticlesTransformAlign p_transform_align) = 0; virtual void particles_set_trails(RID p_particles, bool p_enable, float p_length_sec) = 0; - virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses) = 0; + virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) = 0; virtual bool particles_is_inactive(RID p_particles) = 0; virtual void particles_request_process(RID p_particles) = 0; @@ -667,7 +667,7 @@ public: PARTICLES_EMIT_FLAG_CUSTOM = 16 }; - virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; + virtual void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0; enum ParticlesDrawOrder { PARTICLES_DRAW_ORDER_INDEX, @@ -683,7 +683,7 @@ public: virtual AABB particles_get_current_aabb(RID p_particles) = 0; - virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; //this is only used for 2D, in 3D it's automatic + virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; //this is only used for 2D, in 3D it's automatic /* PARTICLES COLLISION API */ @@ -728,7 +728,7 @@ public: virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0; - virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0; + virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform) = 0; virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0; virtual void camera_set_environment(RID p_camera, RID p_env) = 0; virtual void camera_set_camera_effects(RID p_camera, RID p_camera_effects) = 0; @@ -882,9 +882,9 @@ public: VIEWPORT_DEBUG_DRAW_OVERDRAW, VIEWPORT_DEBUG_DRAW_WIREFRAME, VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER, - VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO, - VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, - VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, + VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO, + VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, + VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS, VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE, @@ -1145,7 +1145,7 @@ public: INSTANCE_LIGHT, INSTANCE_REFLECTION_PROBE, INSTANCE_DECAL, - INSTANCE_GI_PROBE, + INSTANCE_VOXEL_GI, INSTANCE_LIGHTMAP, INSTANCE_OCCLUDER, INSTANCE_MAX, @@ -1160,7 +1160,7 @@ public: virtual void instance_set_base(RID p_instance, RID p_base) = 0; virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0; - virtual void instance_set_transform(RID p_instance, const Transform &p_transform) = 0; + virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0; virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0; virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0; virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) = 0; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 8039018f35..d1cf13f5e2 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -106,7 +106,7 @@ public: virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */ virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */ - virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ + virtual Transform3D get_transform_for_eye(XRInterface::Eyes p_eye, const Transform3D &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye); /* if applicable return external texture to render to */ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index 5341390045..e9383db941 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -194,8 +194,8 @@ void XRPositionalTracker::set_tracker_hand(const XRPositionalTracker::TrackerHan }; }; -Transform XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { - Transform new_transform; +Transform3D XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { + Transform3D new_transform; new_transform.basis = get_orientation(); new_transform.origin = get_position(); diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index a5c6459471..dffa61f369 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -93,7 +93,7 @@ public: void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; - Transform get_transform(bool p_adjust_by_reference_frame) const; + Transform3D get_transform(bool p_adjust_by_reference_frame) const; XRPositionalTracker(); ~XRPositionalTracker() {} diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index 5678071857..3122ee685a 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -101,25 +101,25 @@ void XRServer::set_world_scale(real_t p_world_scale) { world_scale = p_world_scale; }; -Transform XRServer::get_world_origin() const { +Transform3D XRServer::get_world_origin() const { return world_origin; }; -void XRServer::set_world_origin(const Transform &p_world_origin) { +void XRServer::set_world_origin(const Transform3D &p_world_origin) { world_origin = p_world_origin; }; -Transform XRServer::get_reference_frame() const { +Transform3D XRServer::get_reference_frame() const { return reference_frame; }; void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { if (primary_interface != nullptr) { // clear our current reference frame or we'll end up double adjusting it - reference_frame = Transform(); + reference_frame = Transform3D(); // requesting our EYE_MONO transform should return our current HMD position - Transform new_reference_frame = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); + Transform3D new_reference_frame = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform3D()); // remove our tilt if (p_rotation_mode == 1) { @@ -145,8 +145,8 @@ void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { }; }; -Transform XRServer::get_hmd_transform() { - Transform hmd_transform; +Transform3D XRServer::get_hmd_transform() { + Transform3D hmd_transform; if (primary_interface != nullptr) { hmd_transform = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, hmd_transform); }; diff --git a/servers/xr_server.h b/servers/xr_server.h index 46243d7fd0..a2482b925a 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -82,8 +82,8 @@ private: Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ real_t world_scale; /* scale by which we multiply our tracker positions */ - Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */ - Transform reference_frame; /* our reference frame */ + Transform3D world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */ + Transform3D reference_frame; /* our reference frame */ uint64_t last_process_usec; /* for frame timing, usec when we did our processing */ uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */ @@ -122,8 +122,8 @@ public: Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world and in the virtual world out of sync */ - Transform get_world_origin() const; - void set_world_origin(const Transform &p_world_origin); + Transform3D get_world_origin() const; + void set_world_origin(const Transform3D &p_world_origin); /* center_on_hmd calculates a new reference frame. This ensures the HMD is positioned to 0,0,0 facing 0,0,-1 (need to verify this direction) @@ -135,13 +135,13 @@ public: Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world and in the virtual world out of sync */ - Transform get_reference_frame() const; + Transform3D get_reference_frame() const; void center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height); /* get_hmd_transform gets our hmd transform (centered between eyes) with most up to date tracking, relative to the origin */ - Transform get_hmd_transform(); + Transform3D get_hmd_transform(); /* Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc. diff --git a/tests/test_class_db.h b/tests/test_class_db.h index 9ef4569c14..17f9baab85 100644 --- a/tests/test_class_db.h +++ b/tests/test_class_db.h @@ -240,10 +240,10 @@ bool arg_default_value_is_assignable_to_type(const Context &p_context, const Var p_arg_type.name == p_context.names_cache.node_path_type; case Variant::NODE_PATH: return p_arg_type.name == p_context.names_cache.node_path_type; - case Variant::TRANSFORM: + case Variant::TRANSFORM3D: case Variant::TRANSFORM2D: case Variant::BASIS: - case Variant::QUAT: + case Variant::QUATERNION: case Variant::PLANE: case Variant::AABB: case Variant::COLOR: diff --git a/tests/test_command_queue.h b/tests/test_command_queue.h index 2f0f62f5c8..f0d4569942 100644 --- a/tests/test_command_queue.h +++ b/tests/test_command_queue.h @@ -127,20 +127,20 @@ public: int func1_count = 0; - void func1(Transform t) { + void func1(Transform3D t) { func1_count++; } - void func2(Transform t, float f) { + void func2(Transform3D t, float f) { func1_count++; } - void func3(Transform t1, Transform t2, Transform t3, Transform t4, Transform t5, Transform t6) { + void func3(Transform3D t1, Transform3D t2, Transform3D t3, Transform3D t4, Transform3D t5, Transform3D t6) { func1_count++; } - Transform func1r(Transform t) { + Transform3D func1r(Transform3D t) { func1_count++; return t; } - Transform func2r(Transform t, float f) { + Transform3D func2r(Transform3D t, float f) { func1_count++; return t; } @@ -156,7 +156,7 @@ public: command_queue.flush_all(); } for (int i = 0; i < message_count_to_read; i++) { - command_queue.wait_and_flush_one(); + command_queue.wait_and_flush(); } message_count_to_read = 0; @@ -175,8 +175,8 @@ public: during_writing = false; writer_threadwork.thread_wait_for_work(); while (!exit_threads) { - Transform tr; - Transform otr; + Transform3D tr; + Transform3D otr; float f = 1; during_writing = true; for (int i = 0; i < message_types_to_write.size(); i++) { @@ -276,50 +276,6 @@ TEST_CASE("[CommandQueue] Test Queue Basics") { ProjectSettings::get_singleton()->property_get_revert(COMMAND_QUEUE_SETTING)); } -TEST_CASE("[CommandQueue] Test Waiting at Queue Full") { - const char *COMMAND_QUEUE_SETTING = "memory/limits/command_queue/multithreading_queue_size_kb"; - ProjectSettings::get_singleton()->set_setting(COMMAND_QUEUE_SETTING, 1); - SharedThreadState sts; - sts.init_threads(); - - int msgs_to_add = 24; // a queue of size 1kB fundamentally cannot fit 24 matrices. - for (int i = 0; i < msgs_to_add; i++) { - sts.add_msg_to_write(SharedThreadState::TEST_MSG_FUNC1_TRANSFORM); - } - sts.writer_threadwork.main_start_work(); - // If we call main_wait_for_done, we will deadlock. So instead... - sts.message_count_to_read = 1; - sts.reader_threadwork.main_start_work(); - sts.reader_threadwork.main_wait_for_done(); - CHECK_MESSAGE(sts.func1_count == 1, - "Reader should have read one message"); - CHECK_MESSAGE(sts.during_writing, - "Writer thread should still be blocked on writing."); - sts.message_count_to_read = msgs_to_add - 3; - sts.reader_threadwork.main_start_work(); - sts.reader_threadwork.main_wait_for_done(); - CHECK_MESSAGE(sts.func1_count >= msgs_to_add - 3, - "Reader should have read most messages"); - sts.writer_threadwork.main_wait_for_done(); - CHECK_MESSAGE(sts.during_writing == false, - "Writer thread should no longer be blocked on writing."); - sts.message_count_to_read = 2; - sts.reader_threadwork.main_start_work(); - sts.reader_threadwork.main_wait_for_done(); - sts.message_count_to_read = -1; - sts.reader_threadwork.main_start_work(); - sts.reader_threadwork.main_wait_for_done(); - CHECK_MESSAGE(sts.func1_count == msgs_to_add, - "Reader should have read all messages"); - - sts.destroy_threads(); - - CHECK_MESSAGE(sts.func1_count == msgs_to_add, - "Reader should have read no additional messages after join"); - ProjectSettings::get_singleton()->set_setting(COMMAND_QUEUE_SETTING, - ProjectSettings::get_singleton()->property_get_revert(COMMAND_QUEUE_SETTING)); -} - TEST_CASE("[CommandQueue] Test Queue Wrapping to same spot.") { const char *COMMAND_QUEUE_SETTING = "memory/limits/command_queue/multithreading_queue_size_kb"; ProjectSettings::get_singleton()->set_setting(COMMAND_QUEUE_SETTING, 1); diff --git a/tests/test_macros.h b/tests/test_macros.h index a13f3abbe7..a1f1932db4 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -91,10 +91,10 @@ DOCTEST_STRINGIFY_VARIANT(Vector3); DOCTEST_STRINGIFY_VARIANT(Vector3i); DOCTEST_STRINGIFY_VARIANT(Transform2D); DOCTEST_STRINGIFY_VARIANT(Plane); -DOCTEST_STRINGIFY_VARIANT(Quat); +DOCTEST_STRINGIFY_VARIANT(Quaternion); DOCTEST_STRINGIFY_VARIANT(AABB); DOCTEST_STRINGIFY_VARIANT(Basis); -DOCTEST_STRINGIFY_VARIANT(Transform); +DOCTEST_STRINGIFY_VARIANT(Transform3D); DOCTEST_STRINGIFY_VARIANT(::Color); // Disambiguate from `doctest::Color`. DOCTEST_STRINGIFY_VARIANT(StringName); diff --git a/tests/test_math.cpp b/tests/test_math.cpp index 88c32713ed..7f2097699a 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -35,7 +35,7 @@ #include "core/math/delaunay_3d.h" #include "core/math/geometry_2d.h" #include "core/math/math_funcs.h" -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -599,13 +599,13 @@ MainLoop *test() { Basis m2(v2, a2); - Quat q = m; - Quat q2 = m2; + Quaternion q = m; + Quaternion q2 = m2; Basis m3 = m.inverse() * m2; - Quat q3 = (q.inverse() * q2); //.normalized(); + Quaternion q3 = (q.inverse() * q2); //.normalized(); - print_line(Quat(m3)); + print_line(Quaternion(m3)); print_line(q3); print_line("before v: " + v + " a: " + rtos(a)); diff --git a/tests/test_object.h b/tests/test_object.h index 142d76553d..a12fad51e2 100644 --- a/tests/test_object.h +++ b/tests/test_object.h @@ -93,35 +93,8 @@ public: Ref<Script> get_script() const override { return Ref<Script>(); } - Vector<ScriptNetData> get_rpc_methods() const override { - return Vector<ScriptNetData>(); - } - uint16_t get_rpc_method_id(const StringName &p_method) const override { - return 0; - } - StringName get_rpc_method(uint16_t p_id) const override { - return StringName(); - } - MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override { - return MultiplayerAPI::RPC_MODE_PUPPET; - } - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override { - return MultiplayerAPI::RPC_MODE_PUPPET; - } - Vector<ScriptNetData> get_rset_properties() const override { - return Vector<ScriptNetData>(); - } - uint16_t get_rset_property_id(const StringName &p_variable) const override { - return 0; - } - StringName get_rset_property(uint16_t p_id) const override { - return StringName(); - } - MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override { - return MultiplayerAPI::RPC_MODE_PUPPET; - } - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override { - return MultiplayerAPI::RPC_MODE_PUPPET; + const Vector<MultiplayerAPI::RPCConfig> get_rpc_methods() const override { + return Vector<MultiplayerAPI::RPCConfig>(); } ScriptLanguage *get_language() override { return nullptr; diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp index 727c44b3ac..4488e4bf64 100644 --- a/tests/test_physics_3d.cpp +++ b/tests/test_physics_3d.cpp @@ -70,14 +70,14 @@ class TestPhysics3DMainLoop : public MainLoop { void body_changed_transform(Object *p_state, RID p_visual_instance) { PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; RenderingServer *vs = RenderingServer::get_singleton(); - Transform t = state->get_transform(); + Transform3D t = state->get_transform(); vs->instance_set_transform(p_visual_instance, t); } bool quit; protected: - RID create_body(PhysicsServer3D::ShapeType p_shape, PhysicsServer3D::BodyMode p_body, const Transform p_location, bool p_active_default = true, const Transform &p_shape_xform = Transform()) { + RID create_body(PhysicsServer3D::ShapeType p_shape, PhysicsServer3D::BodyMode p_body, const Transform3D p_location, bool p_active_default = true, const Transform3D &p_shape_xform = Transform3D()) { RenderingServer *vs = RenderingServer::get_singleton(); PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); @@ -179,7 +179,7 @@ protected: type_shape_map[PhysicsServer3D::SHAPE_CONVEX_POLYGON] = convex_shape; } - void make_trimesh(Vector<Vector3> p_faces, const Transform &p_xform = Transform()) { + void make_trimesh(Vector<Vector3> p_faces, const Transform3D &p_xform = Transform3D()) { RenderingServer *vs = RenderingServer::get_singleton(); PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); RID trimesh_shape = ps->shape_create(PhysicsServer3D::SHAPE_CONCAVE_POLYGON); @@ -209,12 +209,12 @@ protected: ps->body_set_space(tribody, space); //todo set space ps->body_add_shape(tribody, trimesh_shape); - Transform tritrans = p_xform; + Transform3D tritrans = p_xform; ps->body_set_state(tribody, PhysicsServer3D::BODY_STATE_TRANSFORM, tritrans); vs->instance_set_transform(triins, tritrans); } - void make_grid(int p_width, int p_height, real_t p_cellsize, real_t p_cellheight, const Transform &p_xform = Transform()) { + void make_grid(int p_width, int p_height, real_t p_cellsize, real_t p_cellheight, const Transform3D &p_xform = Transform3D()) { Vector<Vector<real_t>> grid; grid.resize(p_width); @@ -261,7 +261,7 @@ public: if (mover.is_valid()) { PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); - Transform t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM); + Transform3D t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM); t.origin += Vector3(x, y, 0); ps->body_set_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM, t); @@ -287,7 +287,7 @@ public: scenario = vs->scenario_create(); vs->light_set_shadow(lightaux, true); light = vs->instance_create2(lightaux, scenario); - Transform t; + Transform3D t; t.rotate(Vector3(1.0, 0, 0), 0.6); vs->instance_set_transform(light, t); @@ -304,9 +304,9 @@ public: vs->viewport_set_scenario(viewport, scenario); vs->camera_set_perspective(camera, 60, 0.1, 40.0); - vs->camera_set_transform(camera, Transform(Basis(), Vector3(0, 9, 12))); + vs->camera_set_transform(camera, Transform3D(Basis(), Vector3(0, 9, 12))); - Transform gxf; + Transform3D gxf; gxf.basis.scale(Vector3(1.4, 0.4, 1.4)); gxf.origin = Vector3(-2, 1, -2); make_grid(5, 5, 2.5, 1, gxf); @@ -317,12 +317,12 @@ public: if (mover.is_valid()) { static real_t joy_speed = 10; PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); - Transform t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM); + Transform3D t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM); t.origin += Vector3(joy_speed * joy_direction.x * p_time, -joy_speed * joy_direction.y * p_time, 0); ps->body_set_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM, t); }; - Transform cameratr; + Transform3D cameratr; cameratr.rotate(Vector3(0, 1, 0), ofs_x); cameratr.rotate(Vector3(1, 0, 0), -ofs_y); cameratr.translate(Vector3(0, 2, 8)); @@ -355,20 +355,20 @@ public: Dictionary capsule_params; capsule_params["radius"] = 0.5; capsule_params["height"] = 1; - Transform shape_xform; + Transform3D shape_xform; shape_xform.rotate(Vector3(1, 0, 0), Math_PI / 2.0); //shape_xform.origin=Vector3(1,1,1); ps->shape_set_data(capsule_shape, capsule_params); RID mesh_instance = vs->instance_create2(capsule_mesh, scenario); character = ps->body_create(); - ps->body_set_mode(character, PhysicsServer3D::BODY_MODE_CHARACTER); + ps->body_set_mode(character, PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED); ps->body_set_space(character, space); //todo add space ps->body_add_shape(character, capsule_shape); ps->body_set_force_integration_callback(character, callable_mp(this, &TestPhysics3DMainLoop::body_changed_transform), mesh_instance); - ps->body_set_state(character, PhysicsServer3D::BODY_STATE_TRANSFORM, Transform(Basis(), Vector3(-2, 5, -2))); + ps->body_set_state(character, PhysicsServer3D::BODY_STATE_TRANSFORM, Transform3D(Basis(), Vector3(-2, 5, -2))); bodies.push_back(character); } @@ -383,19 +383,19 @@ public: PhysicsServer3D::ShapeType type = shape_idx[i % 4]; - Transform t; + Transform3D t; t.origin = Vector3(0.0 * i, 3.5 + 1.1 * i, 0.7 + 0.0 * i); t.basis.rotate(Vector3(0.2, -1, 0), Math_PI / 2 * 0.6); - create_body(type, PhysicsServer3D::BODY_MODE_RIGID, t); + create_body(type, PhysicsServer3D::BODY_MODE_DYNAMIC, t); } create_static_plane(Plane(Vector3(0, 1, 0), -1)); } void test_activate() { - create_body(PhysicsServer3D::SHAPE_BOX, PhysicsServer3D::BODY_MODE_RIGID, Transform(Basis(), Vector3(0, 2, 0)), true); + create_body(PhysicsServer3D::SHAPE_BOX, PhysicsServer3D::BODY_MODE_DYNAMIC, Transform3D(Basis(), Vector3(0, 2, 0)), true); create_static_plane(Plane(Vector3(0, 1, 0), -1)); } diff --git a/tests/test_render.cpp b/tests/test_render.cpp index 9737fd03f3..fe223ca258 100644 --- a/tests/test_render.cpp +++ b/tests/test_render.cpp @@ -53,7 +53,7 @@ class TestMainLoop : public MainLoop { struct InstanceInfo { RID instance; - Transform base; + Transform3D base; Vector3 rot_axis; }; @@ -165,7 +165,7 @@ public: vs->viewport_set_active(viewport, true); vs->viewport_attach_camera(viewport, camera); vs->viewport_set_scenario(viewport, scenario); - vs->camera_set_transform(camera, Transform(Basis(), Vector3(0, 3, 30))); + vs->camera_set_transform(camera, Transform3D(Basis(), Vector3(0, 3, 30))); vs->camera_set_perspective(camera, 60, 0.1, 1000); /* @@ -182,7 +182,7 @@ public: vs->light_set_color(lightaux, Color(1.0, 1.0, 1.0)); //vs->light_set_shadow( lightaux, true ); light = vs->instance_create2(lightaux, scenario); - Transform lla; + Transform3D lla; //lla.set_look_at(Vector3(),Vector3(1, -1, 1)); lla.set_look_at(Vector3(), Vector3(0.0, -0.836026, -0.548690)); @@ -201,7 +201,7 @@ public: } virtual bool iteration(float p_time) { RenderingServer *vs = RenderingServer::get_singleton(); - //Transform t; + //Transform3D t; //t.rotate(Vector3(0, 1, 0), ofs); //t.translate(Vector3(0,0,20 )); //vs->camera_set_transform(camera, t); @@ -211,7 +211,7 @@ public: //return quit; for (List<InstanceInfo>::Element *E = instances.front(); E; E = E->next()) { - Transform pre(Basis(E->get().rot_axis, ofs), Vector3()); + Transform3D pre(Basis(E->get().rot_axis, ofs), Vector3()); vs->instance_set_transform(E->get().instance, pre * E->get().base); /* if( !E->next() ) { diff --git a/tests/test_validate_testing.h b/tests/test_validate_testing.h index 6d3eea724c..f301047509 100644 --- a/tests/test_validate_testing.h +++ b/tests/test_validate_testing.h @@ -84,7 +84,7 @@ TEST_SUITE("Validate tests") { Plane plane(Vector3(1, 1, 1), 1.0); INFO(plane); - Quat quat(Vector3(0.5, 1.0, 2.0)); + Quaternion quat(Vector3(0.5, 1.0, 2.0)); INFO(quat); AABB aabb(Vector3(), Vector3(100, 100, 100)); @@ -93,7 +93,7 @@ TEST_SUITE("Validate tests") { Basis basis(quat); INFO(basis); - Transform trans(basis); + Transform3D trans(basis); INFO(trans); Color color(1, 0.5, 0.2, 0.3); |