From c33d2130ccf5481ef06d4dc3299fc5c05b2ee1ba Mon Sep 17 00:00:00 2001 From: Jan van der Weide Date: Sat, 12 Apr 2025 18:40:44 +0200 Subject: [PATCH] feat: modules moved and engine moved to submodule --- .gitmodules | 3 + engine/.clangd | 1 - engine/.editorconfig | 5 +- engine/.git-blame-ignore-revs | 6 + engine/.gitignore | 5 + engine/.pre-commit-config.yaml | 23 +- engine/COPYRIGHT.txt | 7 +- engine/SConstruct | 249 +- engine/core/SCsub | 84 +- engine/core/config/engine.cpp | 16 +- engine/core/config/engine.h | 5 +- engine/core/config/project_settings.cpp | 95 +- engine/core/config/project_settings.h | 6 +- engine/core/core_bind.compat.inc | 6 +- engine/core/core_bind.cpp | 44 +- engine/core/core_bind.h | 35 +- engine/core/core_builders.py | 305 +- engine/core/core_constants.h | 5 +- engine/core/core_globals.h | 5 +- engine/core/core_string_names.h | 5 +- engine/core/crypto/SCsub | 2 +- engine/core/crypto/aes_context.h | 5 +- engine/core/crypto/crypto.h | 5 +- engine/core/crypto/crypto_core.cpp | 14 +- engine/core/crypto/crypto_core.h | 17 +- engine/core/crypto/hashing_context.h | 5 +- engine/core/debugger/debugger_marshalls.cpp | 32 +- engine/core/debugger/debugger_marshalls.h | 5 +- engine/core/debugger/engine_debugger.cpp | 8 +- engine/core/debugger/engine_debugger.h | 7 +- engine/core/debugger/engine_profiler.h | 5 +- engine/core/debugger/local_debugger.cpp | 2 +- engine/core/debugger/local_debugger.h | 5 +- engine/core/debugger/remote_debugger.cpp | 44 +- engine/core/debugger/remote_debugger.h | 5 +- engine/core/debugger/remote_debugger_peer.cpp | 2 +- engine/core/debugger/remote_debugger_peer.h | 5 +- engine/core/debugger/script_debugger.cpp | 10 +- engine/core/debugger/script_debugger.h | 8 +- engine/core/doc_data.cpp | 17 +- engine/core/doc_data.h | 13 +- engine/core/error/error_list.cpp | 4 +- engine/core/error/error_list.h | 5 +- engine/core/error/error_macros.cpp | 3 +- engine/core/error/error_macros.h | 27 +- engine/core/extension/extension_api_dump.cpp | 119 +- engine/core/extension/extension_api_dump.h | 5 +- engine/core/extension/gdextension.cpp | 16 + engine/core/extension/gdextension.h | 9 +- .../core/extension/gdextension_interface.cpp | 118 +- engine/core/extension/gdextension_interface.h | 58 +- .../extension/gdextension_library_loader.cpp | 22 +- .../extension/gdextension_library_loader.h | 7 +- engine/core/extension/gdextension_loader.h | 7 +- engine/core/extension/gdextension_manager.h | 5 +- .../gdextension_special_compat_hashes.h | 5 +- .../core/extension/make_interface_dumper.py | 66 +- engine/core/extension/make_wrappers.py | 7 +- .../core/input/default_controller_mappings.h | 5 +- engine/core/input/input.cpp | 6 +- engine/core/input/input.h | 7 +- engine/core/input/input_builders.py | 48 +- engine/core/input/input_enums.h | 11 +- engine/core/input/input_event.cpp | 6 +- engine/core/input/input_event.h | 7 +- engine/core/input/input_map.cpp | 61 +- engine/core/input/input_map.h | 7 +- engine/core/input/shortcut.h | 5 +- engine/core/io/compression.cpp | 26 +- engine/core/io/compression.h | 5 +- engine/core/io/config_file.h | 5 +- engine/core/io/dir_access.cpp | 9 +- engine/core/io/dir_access.h | 6 +- engine/core/io/dtls_server.h | 5 +- engine/core/io/file_access.cpp | 81 +- engine/core/io/file_access.h | 13 +- engine/core/io/file_access_compressed.cpp | 73 +- engine/core/io/file_access_compressed.h | 8 +- engine/core/io/file_access_encrypted.cpp | 44 +- engine/core/io/file_access_encrypted.h | 14 +- engine/core/io/file_access_memory.h | 9 +- engine/core/io/file_access_pack.cpp | 8 +- engine/core/io/file_access_pack.h | 24 +- engine/core/io/file_access_zip.h | 10 +- engine/core/io/http_client.cpp | 9 +- engine/core/io/http_client.h | 5 +- engine/core/io/http_client_tcp.cpp | 13 +- engine/core/io/http_client_tcp.h | 5 +- engine/core/io/image.cpp | 183 +- engine/core/io/image.h | 17 +- engine/core/io/image_loader.h | 5 +- engine/core/io/ip.h | 5 +- engine/core/io/ip_address.cpp | 2 +- engine/core/io/ip_address.h | 7 +- engine/core/io/json.cpp | 165 +- engine/core/io/json.h | 5 +- engine/core/io/logger.cpp | 5 +- engine/core/io/logger.h | 5 +- engine/core/io/marshalls.cpp | 13 +- engine/core/io/marshalls.h | 5 +- engine/core/io/missing_resource.h | 5 +- engine/core/io/net_socket.h | 5 +- engine/core/io/packed_data_container.cpp | 8 +- engine/core/io/packed_data_container.h | 5 +- engine/core/io/packet_peer.h | 5 +- engine/core/io/packet_peer_dtls.h | 5 +- engine/core/io/packet_peer_udp.cpp | 26 +- engine/core/io/packet_peer_udp.h | 5 +- engine/core/io/pck_packer.cpp | 9 +- engine/core/io/pck_packer.h | 5 +- engine/core/io/plist.cpp | 12 +- engine/core/io/plist.h | 7 +- engine/core/io/remote_filesystem_client.h | 5 +- engine/core/io/resource.cpp | 38 +- engine/core/io/resource.h | 14 +- engine/core/io/resource_format_binary.cpp | 68 +- engine/core/io/resource_format_binary.h | 5 +- engine/core/io/resource_importer.cpp | 59 +- engine/core/io/resource_importer.h | 11 +- engine/core/io/resource_loader.cpp | 42 +- engine/core/io/resource_loader.h | 12 +- engine/core/io/resource_saver.h | 5 +- engine/core/io/resource_uid.cpp | 27 +- engine/core/io/resource_uid.h | 6 +- engine/core/io/stream_peer.cpp | 117 +- engine/core/io/stream_peer.h | 9 +- engine/core/io/stream_peer_gzip.cpp | 6 +- engine/core/io/stream_peer_gzip.h | 5 +- engine/core/io/stream_peer_tcp.h | 5 +- engine/core/io/stream_peer_tls.h | 5 +- engine/core/io/tcp_server.h | 5 +- engine/core/io/translation_loader_po.cpp | 23 +- engine/core/io/translation_loader_po.h | 5 +- engine/core/io/udp_server.h | 5 +- engine/core/io/xml_parser.cpp | 3 +- engine/core/io/xml_parser.h | 5 +- engine/core/io/zip_io.cpp | 3 +- engine/core/io/zip_io.h | 5 +- engine/core/math/a_star.cpp | 7 +- engine/core/math/a_star.h | 5 +- engine/core/math/a_star_grid_2d.cpp | 21 +- engine/core/math/a_star_grid_2d.h | 5 +- engine/core/math/aabb.cpp | 12 +- engine/core/math/aabb.h | 19 +- engine/core/math/audio_frame.h | 77 +- engine/core/math/basis.cpp | 60 +- engine/core/math/basis.h | 82 +- engine/core/math/bvh.h | 11 +- engine/core/math/bvh_abb.h | 7 +- engine/core/math/bvh_tree.h | 6 +- engine/core/math/color.cpp | 218 +- engine/core/math/color.h | 171 +- engine/core/math/color_names.inc | 4 + engine/core/math/convex_hull.cpp | 2 +- engine/core/math/convex_hull.h | 5 +- engine/core/math/delaunay_2d.h | 5 +- engine/core/math/delaunay_3d.h | 10 +- engine/core/math/disjoint_set.h | 7 +- engine/core/math/dynamic_bvh.cpp | 2 +- engine/core/math/dynamic_bvh.h | 5 +- engine/core/math/expression.cpp | 8 +- engine/core/math/expression.h | 5 +- engine/core/math/face3.cpp | 2 +- engine/core/math/face3.h | 15 +- engine/core/math/geometry_2d.cpp | 68 +- engine/core/math/geometry_2d.h | 61 +- engine/core/math/geometry_3d.cpp | 19 +- engine/core/math/geometry_3d.h | 64 +- engine/core/math/math_defs.h | 29 +- engine/core/math/math_fieldwise.cpp | 4 +- engine/core/math/math_fieldwise.h | 9 +- engine/core/math/math_funcs.cpp | 29 +- engine/core/math/math_funcs.h | 1426 +- engine/core/math/plane.cpp | 6 +- engine/core/math/plane.h | 27 +- engine/core/math/projection.cpp | 175 +- engine/core/math/projection.h | 53 +- engine/core/math/quaternion.cpp | 20 +- engine/core/math/quaternion.h | 99 +- engine/core/math/quick_hull.cpp | 5 +- engine/core/math/quick_hull.h | 5 +- engine/core/math/random_number_generator.h | 5 +- engine/core/math/random_pcg.h | 9 +- engine/core/math/rect2.cpp | 4 + engine/core/math/rect2.h | 17 +- engine/core/math/rect2i.h | 16 +- engine/core/math/static_raycaster.h | 19 +- engine/core/math/transform_2d.cpp | 52 +- engine/core/math/transform_2d.h | 98 +- engine/core/math/transform_3d.cpp | 51 +- engine/core/math/transform_3d.h | 62 +- engine/core/math/transform_interpolator.h | 5 +- engine/core/math/triangle_mesh.cpp | 101 +- engine/core/math/triangle_mesh.h | 32 +- engine/core/math/triangulate.h | 5 +- engine/core/math/vector2.cpp | 4 + engine/core/math/vector2.h | 107 +- engine/core/math/vector2i.cpp | 69 - engine/core/math/vector2i.h | 151 +- engine/core/math/vector3.cpp | 4 + engine/core/math/vector3.h | 103 +- engine/core/math/vector3i.h | 118 +- engine/core/math/vector4.cpp | 4 + engine/core/math/vector4.h | 108 +- engine/core/math/vector4i.h | 119 +- engine/core/object/callable_method_pointer.h | 14 +- engine/core/object/class_db.cpp | 188 +- engine/core/object/class_db.h | 64 +- engine/core/object/make_virtuals.py | 96 +- engine/core/object/message_queue.cpp | 4 +- engine/core/object/message_queue.h | 5 +- engine/core/object/method_bind.h | 37 +- engine/core/object/object.cpp | 107 +- engine/core/object/object.h | 203 +- engine/core/object/object_id.h | 6 +- engine/core/object/ref_counted.h | 66 +- engine/core/object/script_instance.h | 5 +- engine/core/object/script_language.cpp | 1 + engine/core/object/script_language.h | 6 +- .../core/object/script_language_extension.h | 27 +- engine/core/object/undo_redo.h | 5 +- engine/core/object/worker_thread_pool.cpp | 115 +- engine/core/object/worker_thread_pool.h | 17 +- engine/core/os/condition_variable.h | 5 +- engine/core/os/keyboard.cpp | 6 +- engine/core/os/keyboard.h | 5 +- engine/core/os/main_loop.h | 5 +- engine/core/os/memory.h | 25 +- engine/core/os/midi_driver.h | 5 +- engine/core/os/mutex.h | 5 +- engine/core/os/os.cpp | 14 +- engine/core/os/os.h | 14 +- engine/core/os/rw_lock.h | 5 +- engine/core/os/safe_binary_mutex.h | 14 +- engine/core/os/semaphore.h | 9 +- engine/core/os/shared_object.h | 5 +- engine/core/os/spin_lock.h | 5 +- engine/core/os/thread.h | 18 +- engine/core/os/thread_safe.h | 5 +- engine/core/os/time.cpp | 32 +- engine/core/os/time.h | 5 +- engine/core/os/time_enums.h | 5 +- engine/core/register_core_types.cpp | 157 +- engine/core/register_core_types.h | 5 +- engine/core/string/char_range.inc | 45 +- engine/core/string/char_utils.h | 46 +- engine/core/string/fuzzy_search.h | 5 +- engine/core/string/locales.h | 5 +- engine/core/string/node_path.cpp | 6 +- engine/core/string/node_path.h | 7 +- engine/core/string/optimized_translation.cpp | 19 +- engine/core/string/optimized_translation.h | 7 +- engine/core/string/print_string.cpp | 2 +- engine/core/string/print_string.h | 5 +- engine/core/string/string_buffer.h | 5 +- engine/core/string/string_builder.h | 5 +- engine/core/string/string_name.h | 52 +- engine/core/string/translation.cpp | 6 +- engine/core/string/translation.h | 5 +- engine/core/string/translation_domain.cpp | 2 +- engine/core/string/translation_domain.h | 5 +- engine/core/string/translation_po.cpp | 21 +- engine/core/string/translation_po.h | 5 +- engine/core/string/translation_server.cpp | 12 +- engine/core/string/translation_server.h | 5 +- engine/core/string/ucaps.h | 5 +- engine/core/string/ustring.cpp | 968 +- engine/core/string/ustring.h | 215 +- engine/core/templates/a_hash_map.h | 13 +- engine/core/templates/bin_sorted_array.h | 5 +- engine/core/templates/bit_field.h | 73 + engine/core/templates/command_queue_mt.h | 7 +- engine/core/templates/cowdata.h | 101 +- engine/core/templates/hash_map.h | 5 +- engine/core/templates/hash_set.h | 8 +- engine/core/templates/hashfuncs.h | 63 +- engine/core/templates/list.h | 5 +- engine/core/templates/local_vector.h | 49 +- engine/core/templates/lru.h | 33 +- engine/core/templates/oa_hash_map.h | 6 +- engine/core/templates/paged_allocator.h | 7 +- engine/core/templates/paged_array.h | 5 +- engine/core/templates/pair.h | 11 +- engine/core/templates/pass_func.h | 5 +- engine/core/templates/pooled_list.h | 5 +- engine/core/templates/rb_map.h | 5 +- engine/core/templates/rb_set.h | 5 +- engine/core/templates/rid.h | 6 +- engine/core/templates/rid_owner.h | 7 +- engine/core/templates/ring_buffer.h | 5 +- engine/core/templates/safe_list.h | 6 +- engine/core/templates/safe_refcount.h | 7 +- engine/core/templates/search_array.h | 9 +- engine/core/templates/self_list.h | 5 +- engine/core/templates/simple_type.h | 5 +- engine/core/templates/sort_array.h | 12 +- engine/core/templates/span.h | 124 + engine/core/templates/tuple.h | 9 +- engine/core/templates/vector.h | 52 +- engine/core/templates/vmap.h | 11 +- engine/core/templates/vset.h | 5 +- engine/core/typedefs.h | 102 +- engine/core/variant/array.cpp | 56 +- engine/core/variant/array.h | 17 +- engine/core/variant/binder_common.h | 109 +- engine/core/variant/callable.cpp | 2 +- engine/core/variant/callable.h | 13 +- engine/core/variant/callable_bind.h | 5 +- engine/core/variant/container_type_validate.h | 5 +- engine/core/variant/dictionary.cpp | 28 +- engine/core/variant/dictionary.h | 17 +- engine/core/variant/method_ptrcall.h | 162 +- engine/core/variant/native_ptr.h | 5 +- engine/core/variant/type_info.h | 143 +- engine/core/variant/typed_array.h | 35 +- engine/core/variant/typed_dictionary.h | 58 +- engine/core/variant/variant.cpp | 132 +- engine/core/variant/variant.h | 58 +- engine/core/variant/variant_call.cpp | 99 +- engine/core/variant/variant_callable.h | 5 +- engine/core/variant/variant_construct.h | 5 +- engine/core/variant/variant_destruct.h | 5 +- engine/core/variant/variant_internal.h | 220 +- engine/core/variant/variant_op.h | 15 +- engine/core/variant/variant_parser.cpp | 112 +- engine/core/variant/variant_parser.h | 5 +- engine/core/variant/variant_setget.cpp | 20 +- engine/core/variant/variant_setget.h | 5 +- engine/core/variant/variant_utility.cpp | 6 +- engine/core/variant/variant_utility.h | 5 +- engine/core/version.h | 65 +- engine/doc/classes/@GlobalScope.xml | 2 +- engine/doc/classes/AcceptDialog.xml | 6 +- engine/doc/classes/AnimatedSprite2D.xml | 2 +- engine/doc/classes/AnimatedSprite3D.xml | 2 +- engine/doc/classes/AnimationMixer.xml | 2 +- engine/doc/classes/AnimationPlayer.xml | 4 +- engine/doc/classes/Array.xml | 6 +- engine/doc/classes/AudioEffectPhaser.xml | 2 +- engine/doc/classes/AudioStreamPlayer3D.xml | 4 +- engine/doc/classes/BaseMaterial3D.xml | 2 +- engine/doc/classes/BoneAttachment3D.xml | 2 +- engine/doc/classes/Button.xml | 3 + engine/doc/classes/Camera2D.xml | 3 + engine/doc/classes/CameraServer.xml | 6 + engine/doc/classes/CanvasItem.xml | 87 +- engine/doc/classes/CanvasLayer.xml | 2 +- engine/doc/classes/CharacterBody2D.xml | 4 +- engine/doc/classes/CharacterBody3D.xml | 4 +- engine/doc/classes/CheckBox.xml | 6 + engine/doc/classes/CheckButton.xml | 6 + engine/doc/classes/CodeEdit.xml | 6 +- engine/doc/classes/Color.xml | 4 + engine/doc/classes/ColorPicker.xml | 12 + engine/doc/classes/Control.xml | 53 +- engine/doc/classes/Dictionary.xml | 10 +- engine/doc/classes/DirAccess.xml | 8 + engine/doc/classes/DisplayServer.xml | 971 +- engine/doc/classes/EditorExportPlatform.xml | 1 + engine/doc/classes/EditorExportPlugin.xml | 10 + engine/doc/classes/EditorExportPreset.xml | 13 +- engine/doc/classes/EditorInspector.xml | 1 + engine/doc/classes/EditorInterface.xml | 12 +- engine/doc/classes/EditorPlugin.xml | 30 +- engine/doc/classes/EditorProperty.xml | 1 + engine/doc/classes/EditorSelection.xml | 11 +- engine/doc/classes/EditorSettings.xml | 43 +- engine/doc/classes/FileAccess.xml | 24 +- engine/doc/classes/FoldableContainer.xml | 144 + engine/doc/classes/FoldableGroup.xml | 39 + engine/doc/classes/FontFile.xml | 3 + engine/doc/classes/GraphEdit.xml | 23 + engine/doc/classes/GraphNode.xml | 7 + engine/doc/classes/Image.xml | 23 + engine/doc/classes/InputMap.xml | 7 + engine/doc/classes/JSONRPC.xml | 9 +- engine/doc/classes/JavaClassWrapper.xml | 1 + engine/doc/classes/Label.xml | 7 + engine/doc/classes/Label3D.xml | 5 +- engine/doc/classes/Light3D.xml | 2 +- engine/doc/classes/LineEdit.xml | 6 +- engine/doc/classes/LinkButton.xml | 2 +- engine/doc/classes/LookAtModifier3D.xml | 2 +- engine/doc/classes/Material.xml | 2 +- engine/doc/classes/MenuBar.xml | 1 + engine/doc/classes/MenuButton.xml | 2 +- engine/doc/classes/Mesh.xml | 2 +- .../doc/classes/MultiplayerAPIExtension.xml | 5 + engine/doc/classes/NativeMenu.xml | 2 +- .../NavigationPathQueryParameters2D.xml | 8 + .../NavigationPathQueryParameters3D.xml | 8 + engine/doc/classes/NavigationServer2D.xml | 53 +- engine/doc/classes/NavigationServer3D.xml | 2 +- engine/doc/classes/Node.xml | 69 +- engine/doc/classes/Node3D.xml | 197 +- engine/doc/classes/OS.xml | 16 +- engine/doc/classes/Object.xml | 129 +- engine/doc/classes/OptionButton.xml | 16 + engine/doc/classes/PackedByteArray.xml | 48 +- engine/doc/classes/PackedColorArray.xml | 10 +- engine/doc/classes/PackedFloat32Array.xml | 11 +- engine/doc/classes/PackedFloat64Array.xml | 11 +- engine/doc/classes/PackedInt32Array.xml | 10 +- engine/doc/classes/PackedInt64Array.xml | 10 +- engine/doc/classes/PackedStringArray.xml | 10 +- engine/doc/classes/PackedVector2Array.xml | 11 +- engine/doc/classes/PackedVector3Array.xml | 11 +- engine/doc/classes/PackedVector4Array.xml | 13 +- engine/doc/classes/Path3D.xml | 9 + engine/doc/classes/Performance.xml | 82 +- .../doc/classes/PhysicsDirectSpaceState2D.xml | 4 +- .../doc/classes/PhysicsDirectSpaceState3D.xml | 2 +- engine/doc/classes/Popup.xml | 3 + engine/doc/classes/PopupMenu.xml | 16 + .../classes/PortableCompressedTexture2D.xml | 2 + engine/doc/classes/PrimitiveMesh.xml | 2 +- engine/doc/classes/ProjectSettings.xml | 241 +- engine/doc/classes/Projection.xml | 2 +- engine/doc/classes/RDTextureView.xml | 2 +- engine/doc/classes/RDVertexAttribute.xml | 2 +- engine/doc/classes/RenderingDevice.xml | 42 +- engine/doc/classes/RenderingServer.xml | 55 +- .../classes/ResourceImporterDynamicFont.xml | 3 + engine/doc/classes/ResourceUID.xml | 7 + engine/doc/classes/RichTextLabel.xml | 29 +- engine/doc/classes/SceneState.xml | 12 + engine/doc/classes/SceneTree.xml | 27 +- engine/doc/classes/ScriptLanguage.xml | 2 + engine/doc/classes/ScrollBar.xml | 1 + engine/doc/classes/Signal.xml | 125 +- engine/doc/classes/Skeleton3D.xml | 19 +- engine/doc/classes/SkeletonModifier3D.xml | 15 +- engine/doc/classes/SpringBoneSimulator3D.xml | 10 +- engine/doc/classes/SpriteBase3D.xml | 2 +- engine/doc/classes/StreamPeer.xml | 2 +- engine/doc/classes/StreamPeerGZIP.xml | 3 +- engine/doc/classes/String.xml | 80 +- engine/doc/classes/StringName.xml | 70 +- engine/doc/classes/SystemFont.xml | 3 + engine/doc/classes/TabBar.xml | 8 +- engine/doc/classes/TabContainer.xml | 3 + engine/doc/classes/TextEdit.xml | 7 + engine/doc/classes/TextLine.xml | 6 + engine/doc/classes/TextParagraph.xml | 12 + engine/doc/classes/TextServer.xml | 123 +- engine/doc/classes/TextServerExtension.xml | 114 + engine/doc/classes/TileData.xml | 4 +- engine/doc/classes/TileMapLayer.xml | 9 +- engine/doc/classes/TileSet.xml | 13 +- engine/doc/classes/TileSetAtlasSource.xml | 6 +- .../classes/TileSetScenesCollectionSource.xml | 6 +- engine/doc/classes/Tree.xml | 13 +- engine/doc/classes/TreeItem.xml | 27 +- engine/doc/classes/TriangleMesh.xml | 51 +- engine/doc/classes/Tween.xml | 32 +- engine/doc/classes/UDPServer.xml | 2 +- engine/doc/classes/Viewport.xml | 61 +- .../doc/classes/VisibleOnScreenNotifier2D.xml | 3 + engine/doc/classes/Window.xml | 42 +- engine/doc/classes/XRCamera3D.xml | 3 + engine/doc/classes/XRController3D.xml | 6 +- engine/doc/classes/XRInterface.xml | 3 + engine/doc/classes/XRNode3D.xml | 1 + engine/doc/tools/doc_status.py | 9 +- engine/doc/tools/make_rst.py | 5 +- engine/doc/translations/de.po | 10 +- engine/doc/translations/es.po | 85 +- engine/doc/translations/fr.po | 161 +- engine/doc/translations/ga.po | 14 - engine/doc/translations/it.po | 28080 ++++++++++- engine/doc/translations/ru.po | 38583 ++++++++++++++++ engine/doc/translations/ta.po | 14 - engine/doc/translations/uk.po | 815 +- engine/doc/translations/zh_CN.po | 5182 ++- engine/doc/translations/zh_TW.po | 6 - engine/drivers/SCsub | 9 +- engine/drivers/accesskit/SCsub | 16 + .../accessibility_driver_accesskit.cpp | 1653 + .../accessibility_driver_accesskit.h | 197 + .../dynwrappers/accesskit-dll_wrap.c | 4319 ++ .../dynwrappers/accesskit-dll_wrap.h | 1574 + .../dynwrappers/accesskit-dylib_wrap.c | 4349 ++ .../dynwrappers/accesskit-dylib_wrap.h | 1594 + .../accesskit/dynwrappers/accesskit-so_wrap.c | 4250 ++ .../accesskit/dynwrappers/accesskit-so_wrap.h | 1558 + engine/drivers/alsa/audio_driver_alsa.h | 5 +- .../drivers/alsamidi/midi_driver_alsamidi.h | 5 +- engine/drivers/apple/SCsub | 1 + engine/drivers/apple/joypad_apple.h | 8 + engine/drivers/apple/joypad_apple.mm | 247 +- engine/drivers/apple/thread_apple.cpp | 129 + engine/drivers/apple/thread_apple.h | 110 + engine/drivers/backtrace/SCsub | 2 +- .../coreaudio/audio_driver_coreaudio.h | 5 +- .../coreaudio/audio_driver_coreaudio.mm | 2 +- engine/drivers/coremidi/SCsub | 2 +- .../drivers/coremidi/midi_driver_coremidi.h | 5 +- ...r_coremidi.cpp => midi_driver_coremidi.mm} | 4 +- engine/drivers/d3d12/SCsub | 14 +- engine/drivers/d3d12/d3d12_godot_nir_bridge.h | 5 +- engine/drivers/d3d12/d3d12ma.cpp | 33 +- engine/drivers/d3d12/dxil_hash.h | 5 +- .../d3d12/rendering_context_driver_d3d12.cpp | 22 +- .../d3d12/rendering_context_driver_d3d12.h | 32 +- .../d3d12/rendering_device_driver_d3d12.cpp | 150 +- .../d3d12/rendering_device_driver_d3d12.h | 48 +- engine/drivers/egl/egl_manager.cpp | 4 +- engine/drivers/egl/egl_manager.h | 5 +- engine/drivers/gl_context/SCsub | 7 +- engine/drivers/gles3/effects/copy_effects.cpp | 2 +- engine/drivers/gles3/effects/copy_effects.h | 5 +- .../drivers/gles3/effects/cubemap_filter.cpp | 6 +- engine/drivers/gles3/effects/cubemap_filter.h | 5 +- engine/drivers/gles3/effects/feed_effects.h | 5 +- engine/drivers/gles3/effects/glow.h | 5 +- engine/drivers/gles3/effects/post_effects.h | 5 +- engine/drivers/gles3/environment/fog.h | 5 +- engine/drivers/gles3/environment/gi.h | 5 +- .../drivers/gles3/rasterizer_canvas_gles3.cpp | 14 +- .../drivers/gles3/rasterizer_canvas_gles3.h | 5 +- engine/drivers/gles3/rasterizer_gles3.cpp | 3 +- engine/drivers/gles3/rasterizer_gles3.h | 6 +- .../drivers/gles3/rasterizer_scene_gles3.cpp | 23 +- engine/drivers/gles3/rasterizer_scene_gles3.h | 7 +- engine/drivers/gles3/shader_gles3.cpp | 4 +- engine/drivers/gles3/shader_gles3.h | 7 +- engine/drivers/gles3/storage/config.cpp | 4 +- engine/drivers/gles3/storage/config.h | 5 +- .../drivers/gles3/storage/light_storage.cpp | 2 +- engine/drivers/gles3/storage/light_storage.h | 5 +- .../gles3/storage/material_storage.cpp | 26 +- .../drivers/gles3/storage/material_storage.h | 5 +- engine/drivers/gles3/storage/mesh_storage.h | 5 +- .../gles3/storage/particles_storage.cpp | 28 +- .../drivers/gles3/storage/particles_storage.h | 5 +- .../storage/render_scene_buffers_gles3.h | 5 +- .../drivers/gles3/storage/texture_storage.cpp | 4 +- .../drivers/gles3/storage/texture_storage.h | 5 +- engine/drivers/gles3/storage/utilities.cpp | 3 + engine/drivers/gles3/storage/utilities.h | 5 +- engine/drivers/metal/SCsub | 2 +- engine/drivers/metal/inflection_map.h | 5 +- .../drivers/metal/metal_device_properties.h | 8 +- .../drivers/metal/metal_device_properties.mm | 8 + engine/drivers/metal/metal_objects.h | 23 +- engine/drivers/metal/metal_objects.mm | 98 +- engine/drivers/metal/metal_utils.h | 7 +- engine/drivers/metal/pixel_formats.h | 14 +- engine/drivers/metal/pixel_formats.mm | 29 +- .../metal/rendering_context_driver_metal.h | 9 +- .../metal/rendering_device_driver_metal.h | 13 +- .../metal/rendering_device_driver_metal.mm | 77 +- engine/drivers/png/SCsub | 4 +- engine/drivers/png/image_loader_png.h | 5 +- engine/drivers/png/png_driver_common.h | 5 +- engine/drivers/png/resource_saver_png.h | 5 +- .../pulseaudio/audio_driver_pulseaudio.cpp | 4 +- .../pulseaudio/audio_driver_pulseaudio.h | 5 +- engine/drivers/register_driver_types.h | 5 +- engine/drivers/unix/dir_access_unix.cpp | 32 +- engine/drivers/unix/dir_access_unix.h | 7 +- engine/drivers/unix/file_access_unix.cpp | 39 +- engine/drivers/unix/file_access_unix.h | 8 +- engine/drivers/unix/file_access_unix_pipe.cpp | 2 +- engine/drivers/unix/file_access_unix_pipe.h | 8 +- engine/drivers/unix/ip_unix.h | 5 +- engine/drivers/unix/net_socket_unix.cpp | 9 +- engine/drivers/unix/net_socket_unix.h | 5 +- engine/drivers/unix/os_unix.cpp | 229 +- engine/drivers/unix/os_unix.h | 39 +- engine/drivers/unix/syslog_logger.h | 5 +- engine/drivers/unix/thread_posix.cpp | 7 + engine/drivers/unix/thread_posix.h | 5 +- engine/drivers/vulkan/SCsub | 4 +- engine/drivers/vulkan/godot_vulkan.h | 5 +- .../rendering_context_driver_vulkan.cpp | 4 +- .../vulkan/rendering_context_driver_vulkan.h | 5 +- .../vulkan/rendering_device_driver_vulkan.cpp | 508 +- .../vulkan/rendering_device_driver_vulkan.h | 54 +- engine/drivers/vulkan/vulkan_hooks.h | 5 +- engine/drivers/wasapi/audio_driver_wasapi.cpp | 14 +- engine/drivers/wasapi/audio_driver_wasapi.h | 5 +- engine/drivers/windows/dir_access_windows.cpp | 48 +- engine/drivers/windows/dir_access_windows.h | 7 +- .../drivers/windows/file_access_windows.cpp | 80 +- engine/drivers/windows/file_access_windows.h | 8 +- .../windows/file_access_windows_pipe.cpp | 2 +- .../windows/file_access_windows_pipe.h | 9 +- engine/drivers/windows/ip_windows.h | 5 +- engine/drivers/windows/net_socket_winsock.h | 5 +- engine/drivers/windows/thread_windows.h | 5 +- engine/drivers/winmidi/midi_driver_winmidi.h | 5 +- engine/drivers/xaudio2/audio_driver_xaudio2.h | 5 +- engine/editor/SCsub | 36 +- engine/editor/action_map_editor.cpp | 24 +- engine/editor/action_map_editor.h | 5 +- engine/editor/add_metadata_dialog.cpp | 2 + engine/editor/add_metadata_dialog.h | 4 +- engine/editor/animation_bezier_editor.cpp | 398 +- engine/editor/animation_bezier_editor.h | 16 +- engine/editor/animation_track_editor.cpp | 205 +- engine/editor/animation_track_editor.h | 13 +- .../editor/animation_track_editor_plugins.cpp | 7 +- .../editor/animation_track_editor_plugins.h | 8 +- engine/editor/audio_stream_preview.h | 5 +- engine/editor/code_editor.cpp | 85 +- engine/editor/code_editor.h | 15 +- engine/editor/connections_dialog.cpp | 83 +- engine/editor/connections_dialog.h | 6 +- engine/editor/create_dialog.cpp | 18 +- engine/editor/create_dialog.h | 5 +- .../debug_adapter/debug_adapter_parser.cpp | 32 +- .../debug_adapter/debug_adapter_parser.h | 7 +- .../debug_adapter/debug_adapter_protocol.cpp | 274 +- .../debug_adapter/debug_adapter_protocol.h | 15 +- .../debug_adapter/debug_adapter_server.h | 5 +- .../debug_adapter/debug_adapter_types.h | 47 +- .../debugger/editor_debugger_inspector.cpp | 300 +- .../debugger/editor_debugger_inspector.h | 36 +- .../editor/debugger/editor_debugger_node.cpp | 164 +- engine/editor/debugger/editor_debugger_node.h | 30 +- .../editor/debugger/editor_debugger_server.h | 5 +- .../editor/debugger/editor_debugger_tree.cpp | 115 +- engine/editor/debugger/editor_debugger_tree.h | 20 +- .../debugger/editor_expression_evaluator.cpp | 4 +- .../debugger/editor_expression_evaluator.h | 5 +- engine/editor/debugger/editor_file_server.cpp | 4 +- engine/editor/debugger/editor_file_server.h | 5 +- .../debugger/editor_performance_profiler.cpp | 2 - .../debugger/editor_performance_profiler.h | 7 +- engine/editor/debugger/editor_profiler.cpp | 5 +- engine/editor/debugger/editor_profiler.h | 5 +- .../debugger/editor_visual_profiler.cpp | 6 +- .../editor/debugger/editor_visual_profiler.h | 5 +- .../debugger/script_editor_debugger.cpp | 1316 +- .../editor/debugger/script_editor_debugger.h | 70 +- engine/editor/dependency_editor.cpp | 80 +- engine/editor/dependency_editor.h | 15 +- engine/editor/directory_create_dialog.cpp | 1 + engine/editor/directory_create_dialog.h | 5 +- engine/editor/doc_tools.cpp | 45 +- engine/editor/doc_tools.h | 6 +- engine/editor/editor_about.cpp | 6 +- engine/editor/editor_about.h | 6 +- engine/editor/editor_asset_installer.cpp | 4 + engine/editor/editor_asset_installer.h | 5 +- engine/editor/editor_atlas_packer.h | 5 +- engine/editor/editor_audio_buses.cpp | 50 +- engine/editor/editor_audio_buses.h | 12 +- engine/editor/editor_autoload_settings.cpp | 32 +- engine/editor/editor_autoload_settings.h | 5 +- engine/editor/editor_build_profile.cpp | 16 +- engine/editor/editor_build_profile.h | 5 +- engine/editor/editor_builders.py | 160 +- engine/editor/editor_command_palette.cpp | 10 +- engine/editor/editor_command_palette.h | 5 +- engine/editor/editor_data.cpp | 41 +- engine/editor/editor_data.h | 17 +- engine/editor/editor_dock_manager.cpp | 17 +- engine/editor/editor_dock_manager.h | 7 +- engine/editor/editor_feature_profile.cpp | 5 +- engine/editor/editor_feature_profile.h | 5 +- engine/editor/editor_file_system.cpp | 108 +- engine/editor/editor_file_system.h | 6 +- engine/editor/editor_folding.cpp | 5 +- engine/editor/editor_folding.h | 7 +- engine/editor/editor_help.cpp | 450 +- engine/editor/editor_help.h | 59 +- engine/editor/editor_help_search.cpp | 5 + engine/editor/editor_help_search.h | 5 +- engine/editor/editor_inspector.cpp | 422 +- engine/editor/editor_inspector.h | 42 +- engine/editor/editor_interface.cpp | 40 +- engine/editor/editor_interface.h | 8 +- engine/editor/editor_layouts_dialog.cpp | 1 + engine/editor/editor_layouts_dialog.h | 5 +- engine/editor/editor_locale_dialog.cpp | 10 +- engine/editor/editor_locale_dialog.h | 5 +- engine/editor/editor_log.cpp | 15 +- engine/editor/editor_log.h | 10 +- engine/editor/editor_main_screen.h | 5 +- .../editor_native_shader_source_visualizer.h | 5 +- engine/editor/editor_node.cpp | 794 +- engine/editor/editor_node.h | 55 +- engine/editor/editor_paths.h | 5 +- engine/editor/editor_properties.cpp | 88 +- engine/editor/editor_properties.h | 7 +- .../editor/editor_properties_array_dict.cpp | 145 +- engine/editor/editor_properties_array_dict.h | 10 +- engine/editor/editor_properties_vector.cpp | 2 + engine/editor/editor_properties_vector.h | 5 +- .../editor/editor_property_name_processor.cpp | 9 +- .../editor/editor_property_name_processor.h | 5 +- engine/editor/editor_resource_picker.cpp | 50 +- engine/editor/editor_resource_picker.h | 9 +- engine/editor/editor_resource_preview.cpp | 7 +- engine/editor/editor_resource_preview.h | 7 +- engine/editor/editor_run.cpp | 11 + engine/editor/editor_run.h | 5 +- engine/editor/editor_run_native.cpp | 6 +- engine/editor/editor_run_native.h | 5 +- engine/editor/editor_script.h | 7 +- engine/editor/editor_sectioned_inspector.cpp | 1 + engine/editor/editor_sectioned_inspector.h | 5 +- engine/editor/editor_settings.cpp | 107 +- engine/editor/editor_settings.h | 10 +- engine/editor/editor_settings_dialog.cpp | 24 +- engine/editor/editor_settings_dialog.h | 6 +- engine/editor/editor_string_names.h | 5 +- engine/editor/editor_translation.cpp | 24 +- engine/editor/editor_translation.h | 5 +- engine/editor/editor_translation_parser.cpp | 3 - engine/editor/editor_translation_parser.h | 7 +- engine/editor/editor_undo_redo_manager.cpp | 4 +- engine/editor/editor_undo_redo_manager.h | 5 +- engine/editor/editor_vcs_interface.h | 5 +- engine/editor/engine_update_label.cpp | 13 +- engine/editor/engine_update_label.h | 5 +- engine/editor/event_listener_line_edit.cpp | 26 +- engine/editor/event_listener_line_edit.h | 7 +- engine/editor/export/codesign.cpp | 19 +- engine/editor/export/codesign.h | 7 +- engine/editor/export/editor_export.cpp | 3 - engine/editor/export/editor_export.h | 6 +- .../export/editor_export_platform.compat.inc | 41 + .../editor/export/editor_export_platform.cpp | 87 +- engine/editor/export/editor_export_platform.h | 16 +- .../export/editor_export_platform_extension.h | 5 +- .../editor/export/editor_export_platform_pc.h | 5 +- engine/editor/export/editor_export_plugin.cpp | 7 + engine/editor/export/editor_export_plugin.h | 7 +- engine/editor/export/editor_export_preset.cpp | 33 +- engine/editor/export/editor_export_preset.h | 9 +- .../editor/export/export_template_manager.cpp | 86 +- .../editor/export/export_template_manager.h | 7 +- engine/editor/export/lipo.h | 5 +- engine/editor/export/macho.h | 5 +- engine/editor/export/project_export.cpp | 77 +- engine/editor/export/project_export.h | 6 +- engine/editor/export/project_zip_packer.cpp | 4 +- engine/editor/export/project_zip_packer.h | 5 +- engine/editor/fbx_importer_manager.cpp | 1 + engine/editor/fbx_importer_manager.h | 5 +- engine/editor/file_info.h | 5 +- engine/editor/filesystem_dock.cpp | 215 +- engine/editor/filesystem_dock.h | 7 +- engine/editor/find_in_files.cpp | 9 +- engine/editor/find_in_files.h | 5 +- engine/editor/group_settings_editor.cpp | 2 + engine/editor/group_settings_editor.h | 5 +- engine/editor/groups_editor.cpp | 7 +- engine/editor/groups_editor.h | 6 +- engine/editor/gui/editor_bottom_panel.cpp | 4 + engine/editor/gui/editor_bottom_panel.h | 5 +- engine/editor/gui/editor_dir_dialog.h | 5 +- engine/editor/gui/editor_file_dialog.cpp | 87 +- engine/editor/gui/editor_file_dialog.h | 5 +- engine/editor/gui/editor_object_selector.cpp | 3 +- engine/editor/gui/editor_object_selector.h | 5 +- .../editor/gui/editor_quick_open_dialog.cpp | 126 +- engine/editor/gui/editor_quick_open_dialog.h | 10 +- engine/editor/gui/editor_run_bar.cpp | 21 +- engine/editor/gui/editor_run_bar.h | 5 +- engine/editor/gui/editor_scene_tabs.cpp | 15 +- engine/editor/gui/editor_scene_tabs.h | 5 +- engine/editor/gui/editor_spin_slider.cpp | 16 +- engine/editor/gui/editor_spin_slider.h | 5 +- engine/editor/gui/editor_title_bar.cpp | 47 + engine/editor/gui/editor_title_bar.h | 11 +- engine/editor/gui/editor_toaster.cpp | 4 + engine/editor/gui/editor_toaster.h | 5 +- engine/editor/gui/editor_validation_panel.h | 5 +- engine/editor/gui/editor_version_button.cpp | 14 +- engine/editor/gui/editor_version_button.h | 5 +- engine/editor/gui/editor_zoom_widget.cpp | 3 + engine/editor/gui/editor_zoom_widget.h | 5 +- engine/editor/gui/scene_tree_editor.cpp | 57 +- engine/editor/gui/scene_tree_editor.h | 11 +- engine/editor/gui/touch_actions_panel.cpp | 184 + engine/editor/gui/touch_actions_panel.h | 70 + engine/editor/history_dock.cpp | 10 +- engine/editor/history_dock.h | 5 +- engine/editor/icons/2D.svg | 2 +- engine/editor/icons/2DNodes.svg | 2 +- engine/editor/icons/3D.svg | 2 +- engine/editor/icons/AABB.svg | 2 +- engine/editor/icons/AcceptDialog.svg | 2 +- engine/editor/icons/ActionCopy.svg | 2 +- engine/editor/icons/ActionCut.svg | 2 +- engine/editor/icons/ActionPaste.svg | 2 +- engine/editor/icons/Add.svg | 2 +- engine/editor/icons/Anchor.svg | 2 +- engine/editor/icons/AnimatableBody2D.svg | 2 +- engine/editor/icons/AnimatableBody3D.svg | 2 +- engine/editor/icons/AnimatedSprite2D.svg | 2 +- engine/editor/icons/AnimatedSprite3D.svg | 2 +- engine/editor/icons/AnimatedTexture.svg | 2 +- engine/editor/icons/Animation.svg | 2 +- engine/editor/icons/AnimationAutoFit.svg | 2 +- .../editor/icons/AnimationAutoFitBezier.svg | 2 +- engine/editor/icons/AnimationFilter.svg | 2 +- engine/editor/icons/AnimationLibrary.svg | 2 +- engine/editor/icons/AnimationMixer.svg | 2 +- engine/editor/icons/AnimationPlayer.svg | 2 +- engine/editor/icons/AnimationTrackGroup.svg | 2 +- engine/editor/icons/AnimationTrackList.svg | 2 +- engine/editor/icons/AnimationTree.svg | 2 +- engine/editor/icons/Area2D.svg | 2 +- engine/editor/icons/Area3D.svg | 2 +- engine/editor/icons/Array.svg | 2 +- engine/editor/icons/ArrayMesh.svg | 2 +- engine/editor/icons/ArrayOccluder3D.svg | 2 +- engine/editor/icons/ArrowDown.svg | 2 +- engine/editor/icons/ArrowLeft.svg | 2 +- engine/editor/icons/ArrowRight.svg | 2 +- engine/editor/icons/ArrowUp.svg | 2 +- engine/editor/icons/AspectRatioContainer.svg | 2 +- engine/editor/icons/AssetLib.svg | 2 +- engine/editor/icons/AtlasTexture.svg | 2 +- engine/editor/icons/AudioBusBypass.svg | 2 +- engine/editor/icons/AudioBusLayout.svg | 2 +- engine/editor/icons/AudioBusMute.svg | 2 +- engine/editor/icons/AudioBusSolo.svg | 2 +- engine/editor/icons/AudioListener2D.svg | 2 +- engine/editor/icons/AudioListener3D.svg | 2 +- engine/editor/icons/AudioMute.svg | 1 + engine/editor/icons/AudioStream.svg | 2 +- engine/editor/icons/AudioStreamGenerator.svg | 2 +- engine/editor/icons/AudioStreamMP3.svg | 2 +- engine/editor/icons/AudioStreamMicrophone.svg | 2 +- engine/editor/icons/AudioStreamOggVorbis.svg | 2 +- engine/editor/icons/AudioStreamPlayer.svg | 2 +- engine/editor/icons/AudioStreamPlayer2D.svg | 2 +- engine/editor/icons/AudioStreamPlayer3D.svg | 2 +- engine/editor/icons/AudioStreamPolyphonic.svg | 2 +- engine/editor/icons/AudioStreamRandomizer.svg | 2 +- engine/editor/icons/AudioStreamWAV.svg | 2 +- engine/editor/icons/AutoEnd.svg | 2 +- engine/editor/icons/AutoKey.svg | 2 +- engine/editor/icons/AutoPlay.svg | 2 +- engine/editor/icons/AutoTriangle.svg | 2 +- engine/editor/icons/Back.svg | 2 +- engine/editor/icons/BackBufferCopy.svg | 2 +- engine/editor/icons/Bake.svg | 2 +- engine/editor/icons/BaseButton.svg | 2 +- engine/editor/icons/Basis.svg | 2 +- engine/editor/icons/BezierHandlesBalanced.svg | 2 +- engine/editor/icons/BezierHandlesFree.svg | 2 +- engine/editor/icons/BezierHandlesLinear.svg | 2 +- engine/editor/icons/BezierHandlesMirror.svg | 2 +- engine/editor/icons/BitMap.svg | 2 +- engine/editor/icons/Blend.svg | 2 +- engine/editor/icons/Bone.svg | 2 +- engine/editor/icons/Bone2D.svg | 2 +- engine/editor/icons/BoneAttachment3D.svg | 2 +- engine/editor/icons/BoneMapHumanBody.svg | 2 +- engine/editor/icons/BoneMapHumanFace.svg | 2 +- engine/editor/icons/BoneMapHumanLeftHand.svg | 2 +- engine/editor/icons/BoneMapHumanRightHand.svg | 2 +- engine/editor/icons/BoneMapperHandle.svg | 2 +- .../editor/icons/BoneMapperHandleCircle.svg | 2 +- .../editor/icons/BoneMapperHandleSelected.svg | 2 +- engine/editor/icons/BoxContainer.svg | 2 +- engine/editor/icons/BoxMesh.svg | 2 +- engine/editor/icons/BoxOccluder3D.svg | 2 +- engine/editor/icons/BoxShape3D.svg | 2 +- engine/editor/icons/Breakpoint.svg | 2 +- engine/editor/icons/Bucket.svg | 2 +- engine/editor/icons/BusVuActive.svg | 2 +- engine/editor/icons/BusVuFrozen.svg | 2 +- engine/editor/icons/Button.svg | 2 +- engine/editor/icons/ButtonGroup.svg | 2 +- engine/editor/icons/CPUParticles2D.svg | 2 +- engine/editor/icons/CPUParticles3D.svg | 2 +- engine/editor/icons/Callable.svg | 2 +- engine/editor/icons/Camera.svg | 2 +- engine/editor/icons/Camera2D.svg | 2 +- engine/editor/icons/Camera3D.svg | 2 +- engine/editor/icons/CameraAttributes.svg | 2 +- .../editor/icons/CameraAttributesPhysical.svg | 2 +- .../icons/CameraAttributesPractical.svg | 2 +- engine/editor/icons/CameraTexture.svg | 2 +- engine/editor/icons/CanvasGroup.svg | 2 +- engine/editor/icons/CanvasItem.svg | 2 +- engine/editor/icons/CanvasItemMaterial.svg | 2 +- engine/editor/icons/CanvasLayer.svg | 2 +- engine/editor/icons/CanvasModulate.svg | 2 +- engine/editor/icons/CanvasTexture.svg | 2 +- engine/editor/icons/CapsuleMesh.svg | 2 +- engine/editor/icons/CapsuleShape2D.svg | 2 +- engine/editor/icons/CapsuleShape3D.svg | 2 +- engine/editor/icons/CenterContainer.svg | 2 +- engine/editor/icons/CenterView.svg | 2 +- engine/editor/icons/CharacterBody2D.svg | 2 +- engine/editor/icons/CharacterBody3D.svg | 2 +- engine/editor/icons/CheckBox.svg | 2 +- engine/editor/icons/CheckButton.svg | 2 +- engine/editor/icons/Checkerboard.svg | 2 +- engine/editor/icons/CircleShape2D.svg | 2 +- engine/editor/icons/ClassList.svg | 2 +- engine/editor/icons/Clear.svg | 2 +- engine/editor/icons/Close.svg | 2 +- engine/editor/icons/CodeEdit.svg | 2 +- engine/editor/icons/CodeFoldDownArrow.svg | 2 +- engine/editor/icons/CodeFoldedRightArrow.svg | 2 +- engine/editor/icons/CodeHighlighter.svg | 2 +- .../editor/icons/CodeRegionFoldDownArrow.svg | 2 +- .../icons/CodeRegionFoldedRightArrow.svg | 2 +- engine/editor/icons/Collapse.svg | 2 +- engine/editor/icons/CollapseTree.svg | 2 +- engine/editor/icons/CollisionPolygon2D.svg | 2 +- engine/editor/icons/CollisionPolygon3D.svg | 2 +- engine/editor/icons/CollisionShape2D.svg | 2 +- engine/editor/icons/CollisionShape3D.svg | 2 +- engine/editor/icons/Color.svg | 2 +- engine/editor/icons/ColorPick.svg | 2 +- engine/editor/icons/ColorPicker.svg | 2 +- engine/editor/icons/ColorPickerBarArrow.svg | 2 +- engine/editor/icons/ColorPickerButton.svg | 2 +- engine/editor/icons/ColorRect.svg | 2 +- engine/editor/icons/ColorTrackVu.svg | 2 +- engine/editor/icons/CombineLines.svg | 2 +- engine/editor/icons/CompressedTexture2D.svg | 2 +- engine/editor/icons/CompressedTexture3D.svg | 2 +- engine/editor/icons/ConcavePolygonShape2D.svg | 2 +- engine/editor/icons/ConcavePolygonShape3D.svg | 2 +- engine/editor/icons/ConeTwistJoint3D.svg | 2 +- engine/editor/icons/ConfirmationDialog.svg | 2 +- engine/editor/icons/Container.svg | 2 +- engine/editor/icons/ContainerLayout.svg | 2 +- engine/editor/icons/Control.svg | 2 +- .../editor/icons/ControlAlignBottomLeft.svg | 2 +- .../editor/icons/ControlAlignBottomRight.svg | 2 +- .../editor/icons/ControlAlignBottomWide.svg | 2 +- engine/editor/icons/ControlAlignCenter.svg | 2 +- .../editor/icons/ControlAlignCenterBottom.svg | 2 +- .../editor/icons/ControlAlignCenterLeft.svg | 2 +- .../editor/icons/ControlAlignCenterRight.svg | 2 +- engine/editor/icons/ControlAlignCenterTop.svg | 2 +- engine/editor/icons/ControlAlignFullRect.svg | 2 +- .../editor/icons/ControlAlignHCenterWide.svg | 2 +- engine/editor/icons/ControlAlignLeftWide.svg | 2 +- engine/editor/icons/ControlAlignRightWide.svg | 2 +- engine/editor/icons/ControlAlignTopLeft.svg | 2 +- engine/editor/icons/ControlAlignTopRight.svg | 2 +- engine/editor/icons/ControlAlignTopWide.svg | 2 +- .../editor/icons/ControlAlignVCenterWide.svg | 2 +- engine/editor/icons/ControlLayout.svg | 2 +- engine/editor/icons/ConvexPolygonShape2D.svg | 2 +- engine/editor/icons/ConvexPolygonShape3D.svg | 2 +- engine/editor/icons/CopyNodePath.svg | 2 +- engine/editor/icons/CreateNewSceneFrom.svg | 2 +- engine/editor/icons/CryptoKey.svg | 2 +- engine/editor/icons/Cubemap.svg | 2 +- engine/editor/icons/CubemapArray.svg | 2 +- engine/editor/icons/Curve.svg | 2 +- engine/editor/icons/Curve2D.svg | 2 +- engine/editor/icons/Curve3D.svg | 2 +- engine/editor/icons/CurveClose.svg | 2 +- engine/editor/icons/CurveConstant.svg | 2 +- engine/editor/icons/CurveCreate.svg | 2 +- engine/editor/icons/CurveCurve.svg | 2 +- engine/editor/icons/CurveDelete.svg | 2 +- engine/editor/icons/CurveEdit.svg | 2 +- engine/editor/icons/CurveIn.svg | 2 +- engine/editor/icons/CurveInOut.svg | 2 +- engine/editor/icons/CurveLinear.svg | 2 +- engine/editor/icons/CurveOut.svg | 2 +- engine/editor/icons/CurveOutIn.svg | 2 +- engine/editor/icons/CurveTexture.svg | 2 +- engine/editor/icons/CurveTilt.svg | 2 +- engine/editor/icons/CurveXYZTexture.svg | 2 +- engine/editor/icons/CylinderMesh.svg | 2 +- engine/editor/icons/CylinderShape3D.svg | 2 +- engine/editor/icons/DampedSpringJoint2D.svg | 2 +- engine/editor/icons/Debug.svg | 2 +- engine/editor/icons/DebugContinue.svg | 2 +- engine/editor/icons/DebugNext.svg | 2 +- .../editor/icons/DebugSkipBreakpointsOff.svg | 2 +- .../editor/icons/DebugSkipBreakpointsOn.svg | 2 +- engine/editor/icons/DebugStep.svg | 2 +- engine/editor/icons/Decal.svg | 2 +- engine/editor/icons/DefaultProjectIcon.svg | 2 +- engine/editor/icons/Dictionary.svg | 2 +- engine/editor/icons/DirAccess.svg | 2 +- engine/editor/icons/DirectionalLight2D.svg | 2 +- engine/editor/icons/DirectionalLight3D.svg | 2 +- engine/editor/icons/DistractionFree.svg | 2 +- engine/editor/icons/DragHandle.svg | 1 + engine/editor/icons/Duplicate.svg | 2 +- engine/editor/icons/Edit.svg | 2 +- engine/editor/icons/EditAddRemove.svg | 2 +- engine/editor/icons/EditBezier.svg | 2 +- engine/editor/icons/EditInternal.svg | 2 +- engine/editor/icons/EditKey.svg | 2 +- engine/editor/icons/EditPivot.svg | 2 +- engine/editor/icons/Editor3DHandle.svg | 2 +- engine/editor/icons/EditorBoneHandle.svg | 2 +- engine/editor/icons/EditorControlAnchor.svg | 2 +- engine/editor/icons/EditorCurveHandle.svg | 2 +- engine/editor/icons/EditorFileDialog.svg | 2 +- engine/editor/icons/EditorHandle.svg | 2 +- engine/editor/icons/EditorHandleAdd.svg | 2 +- engine/editor/icons/EditorHandleDisabled.svg | 2 +- engine/editor/icons/EditorPathSharpHandle.svg | 2 +- .../editor/icons/EditorPathSmoothHandle.svg | 2 +- engine/editor/icons/EditorPivot.svg | 2 +- engine/editor/icons/EditorPlugin.svg | 2 +- engine/editor/icons/EditorPosition.svg | 2 +- .../editor/icons/EditorPositionPrevious.svg | 2 +- .../editor/icons/EditorPositionUnselected.svg | 2 +- engine/editor/icons/Enum.svg | 2 +- engine/editor/icons/Environment.svg | 2 +- engine/editor/icons/Eraser.svg | 2 +- engine/editor/icons/Error.svg | 2 +- engine/editor/icons/ErrorWarning.svg | 2 +- engine/editor/icons/ExpandBottomDock.svg | 2 +- engine/editor/icons/ExpandTree.svg | 2 +- engine/editor/icons/ExternalLink.svg | 2 +- engine/editor/icons/FPS.svg | 2 +- engine/editor/icons/FadeCross.svg | 2 +- engine/editor/icons/FadeDisabled.svg | 2 +- engine/editor/icons/FadeIn.svg | 2 +- engine/editor/icons/FadeOut.svg | 2 +- engine/editor/icons/Favorites.svg | 2 +- engine/editor/icons/File.svg | 2 +- engine/editor/icons/FileAccess.svg | 2 +- engine/editor/icons/FileBigThumb.svg | 2 +- engine/editor/icons/FileBroken.svg | 2 +- engine/editor/icons/FileBrokenBigThumb.svg | 2 +- engine/editor/icons/FileBrowse.svg | 2 +- engine/editor/icons/FileDead.svg | 2 +- engine/editor/icons/FileDeadBigThumb.svg | 2 +- engine/editor/icons/FileDeadMediumThumb.svg | 2 +- engine/editor/icons/FileDialog.svg | 2 +- engine/editor/icons/FileList.svg | 2 +- engine/editor/icons/FileMediumThumb.svg | 2 +- engine/editor/icons/FileThumbnail.svg | 2 +- engine/editor/icons/FileTree.svg | 2 +- engine/editor/icons/FilenameFilter.svg | 2 +- engine/editor/icons/Filesystem.svg | 2 +- engine/editor/icons/FixedSize.svg | 2 +- engine/editor/icons/FlipWinding.svg | 2 +- engine/editor/icons/FlowContainer.svg | 2 +- engine/editor/icons/FogMaterial.svg | 2 +- engine/editor/icons/FogVolume.svg | 2 +- engine/editor/icons/FoldableContainer.svg | 1 + engine/editor/icons/Folder.svg | 2 +- engine/editor/icons/FolderBigThumb.svg | 2 +- engine/editor/icons/FolderBrowse.svg | 2 +- engine/editor/icons/FolderCreate.svg | 2 +- engine/editor/icons/FolderMediumThumb.svg | 2 +- engine/editor/icons/Font.svg | 2 +- engine/editor/icons/FontFile.svg | 2 +- engine/editor/icons/FontItem.svg | 2 +- engine/editor/icons/FontSize.svg | 2 +- engine/editor/icons/FontVariation.svg | 2 +- engine/editor/icons/Forward.svg | 2 +- engine/editor/icons/GPUParticles2D.svg | 2 +- engine/editor/icons/GPUParticles3D.svg | 2 +- .../icons/GPUParticlesAttractorBox3D.svg | 2 +- .../icons/GPUParticlesAttractorSphere3D.svg | 2 +- .../GPUParticlesAttractorVectorField3D.svg | 2 +- .../icons/GPUParticlesCollisionBox3D.svg | 2 +- .../GPUParticlesCollisionHeightField3D.svg | 2 +- .../icons/GPUParticlesCollisionSDF3D.svg | 2 +- .../icons/GPUParticlesCollisionSphere3D.svg | 2 +- engine/editor/icons/Game.svg | 2 +- engine/editor/icons/Generic6DOFJoint3D.svg | 2 +- engine/editor/icons/GeometryInstance3D.svg | 2 +- engine/editor/icons/Gizmo3DSamplePlayer.svg | 2 +- engine/editor/icons/GizmoAudioListener3D.svg | 2 +- engine/editor/icons/GizmoCPUParticles3D.svg | 2 +- engine/editor/icons/GizmoCamera3D.svg | 2 +- engine/editor/icons/GizmoDecal.svg | 2 +- engine/editor/icons/GizmoDirectionalLight.svg | 2 +- engine/editor/icons/GizmoFogVolume.svg | 2 +- engine/editor/icons/GizmoGPUParticles3D.svg | 2 +- engine/editor/icons/GizmoLight.svg | 2 +- engine/editor/icons/GizmoLightmapGI.svg | 2 +- engine/editor/icons/GizmoLightmapProbe.svg | 2 +- engine/editor/icons/GizmoReflectionProbe.svg | 2 +- engine/editor/icons/GizmoSpotLight.svg | 2 +- engine/editor/icons/GizmoVoxelGI.svg | 2 +- engine/editor/icons/Godot.svg | 2 +- engine/editor/icons/GodotFile.svg | 2 +- engine/editor/icons/GodotMonochrome.svg | 2 +- engine/editor/icons/Gradient.svg | 2 +- engine/editor/icons/GradientTexture1D.svg | 2 +- engine/editor/icons/GradientTexture2D.svg | 2 +- engine/editor/icons/GraphEdit.svg | 2 +- engine/editor/icons/GraphElement.svg | 2 +- engine/editor/icons/GraphFrame.svg | 2 +- engine/editor/icons/GraphNode.svg | 2 +- engine/editor/icons/Grid.svg | 2 +- engine/editor/icons/GridContainer.svg | 2 +- engine/editor/icons/GridLayout.svg | 2 +- engine/editor/icons/GridMinimap.svg | 2 +- engine/editor/icons/GridToggle.svg | 2 +- engine/editor/icons/GrooveJoint2D.svg | 2 +- engine/editor/icons/Group.svg | 2 +- engine/editor/icons/GroupViewport.svg | 2 +- engine/editor/icons/Groups.svg | 2 +- engine/editor/icons/GuiArrowUp.svg | 1 + engine/editor/icons/GuiChecked.svg | 2 +- engine/editor/icons/GuiCheckedDisabled.svg | 2 +- engine/editor/icons/GuiClose.svg | 2 +- engine/editor/icons/GuiDropdown.svg | 2 +- engine/editor/icons/GuiEllipsis.svg | 2 +- engine/editor/icons/GuiGraphNodePort.svg | 2 +- engine/editor/icons/GuiHsplitter.svg | 2 +- engine/editor/icons/GuiIndeterminate.svg | 2 +- .../editor/icons/GuiIndeterminateDisabled.svg | 2 +- engine/editor/icons/GuiMiniCheckerboard.svg | 2 +- engine/editor/icons/GuiOptionArrow.svg | 2 +- engine/editor/icons/GuiProgressBar.svg | 2 +- engine/editor/icons/GuiProgressFill.svg | 2 +- engine/editor/icons/GuiRadioChecked.svg | 2 +- .../editor/icons/GuiRadioCheckedDisabled.svg | 2 +- engine/editor/icons/GuiRadioUnchecked.svg | 2 +- .../icons/GuiRadioUncheckedDisabled.svg | 2 +- engine/editor/icons/GuiResizer.svg | 2 +- engine/editor/icons/GuiResizerTopLeft.svg | 2 +- engine/editor/icons/GuiScrollArrowLeft.svg | 2 +- engine/editor/icons/GuiScrollArrowLeftHl.svg | 2 +- engine/editor/icons/GuiScrollArrowRight.svg | 2 +- engine/editor/icons/GuiScrollArrowRightHl.svg | 2 +- engine/editor/icons/GuiScrollBg.svg | 2 +- engine/editor/icons/GuiScrollGrabber.svg | 2 +- engine/editor/icons/GuiScrollGrabberHl.svg | 2 +- .../editor/icons/GuiScrollGrabberPressed.svg | 2 +- engine/editor/icons/GuiSliderGrabber.svg | 2 +- engine/editor/icons/GuiSliderGrabberHl.svg | 2 +- engine/editor/icons/GuiSpace.svg | 2 +- engine/editor/icons/GuiSpinboxDown.svg | 2 +- engine/editor/icons/GuiSpinboxUp.svg | 2 +- engine/editor/icons/GuiSpinboxUpdown.svg | 2 +- .../editor/icons/GuiSpinboxUpdownDisabled.svg | 2 +- engine/editor/icons/GuiTab.svg | 2 +- engine/editor/icons/GuiTabDropMark.svg | 2 +- engine/editor/icons/GuiTabMenu.svg | 2 +- engine/editor/icons/GuiTabMenuHl.svg | 2 +- engine/editor/icons/GuiToggleOff.svg | 2 +- engine/editor/icons/GuiToggleOffDisabled.svg | 2 +- .../icons/GuiToggleOffDisabledMirrored.svg | 2 +- engine/editor/icons/GuiToggleOffMirrored.svg | 2 +- engine/editor/icons/GuiToggleOn.svg | 2 +- engine/editor/icons/GuiToggleOnDisabled.svg | 2 +- .../icons/GuiToggleOnDisabledMirrored.svg | 2 +- engine/editor/icons/GuiToggleOnMirrored.svg | 2 +- engine/editor/icons/GuiTreeArrowDown.svg | 2 +- engine/editor/icons/GuiTreeArrowLeft.svg | 2 +- engine/editor/icons/GuiTreeArrowRight.svg | 2 +- engine/editor/icons/GuiTreeUpdown.svg | 2 +- engine/editor/icons/GuiUnchecked.svg | 2 +- engine/editor/icons/GuiUncheckedDisabled.svg | 2 +- .../editor/icons/GuiViewportHdiagsplitter.svg | 2 +- .../editor/icons/GuiViewportVdiagsplitter.svg | 2 +- engine/editor/icons/GuiViewportVhsplitter.svg | 2 +- engine/editor/icons/GuiVisibilityHidden.svg | 2 +- engine/editor/icons/GuiVisibilityVisible.svg | 2 +- engine/editor/icons/GuiVisibilityXray.svg | 2 +- engine/editor/icons/GuiVsplitter.svg | 2 +- engine/editor/icons/HBoxContainer.svg | 2 +- engine/editor/icons/HFlowContainer.svg | 2 +- engine/editor/icons/HScrollBar.svg | 2 +- engine/editor/icons/HSeparator.svg | 2 +- engine/editor/icons/HSlider.svg | 2 +- engine/editor/icons/HSplitContainer.svg | 2 +- engine/editor/icons/HTTPRequest.svg | 2 +- engine/editor/icons/Heart.svg | 2 +- engine/editor/icons/HeightMapShape3D.svg | 2 +- engine/editor/icons/Help.svg | 2 +- engine/editor/icons/HelpSearch.svg | 2 +- engine/editor/icons/HingeJoint3D.svg | 2 +- engine/editor/icons/History.svg | 2 +- engine/editor/icons/Hsize.svg | 2 +- engine/editor/icons/IOSDeviceWired.svg | 2 +- engine/editor/icons/IOSDeviceWireless.svg | 2 +- engine/editor/icons/IOSSimulator.svg | 2 +- engine/editor/icons/Image.svg | 2 +- engine/editor/icons/ImageTexture.svg | 2 +- engine/editor/icons/ImageTexture3D.svg | 2 +- engine/editor/icons/ImmediateMesh.svg | 2 +- engine/editor/icons/ImportCheck.svg | 2 +- engine/editor/icons/ImportFail.svg | 2 +- .../editor/icons/ImporterMeshInstance3D.svg | 2 +- engine/editor/icons/Info.svg | 2 +- engine/editor/icons/InputEventAction.svg | 2 +- .../editor/icons/InputEventJoypadButton.svg | 2 +- .../editor/icons/InputEventJoypadMotion.svg | 2 +- engine/editor/icons/InputEventKey.svg | 2 +- engine/editor/icons/InputEventMIDI.svg | 2 +- .../editor/icons/InputEventMagnifyGesture.svg | 2 +- engine/editor/icons/InputEventMouseButton.svg | 2 +- engine/editor/icons/InputEventMouseMotion.svg | 2 +- engine/editor/icons/InputEventPanGesture.svg | 2 +- engine/editor/icons/InputEventScreenDrag.svg | 2 +- engine/editor/icons/InputEventScreenTouch.svg | 2 +- engine/editor/icons/InputEventShortcut.svg | 2 +- engine/editor/icons/InsertAfter.svg | 2 +- engine/editor/icons/InsertBefore.svg | 2 +- engine/editor/icons/Instance.svg | 2 +- engine/editor/icons/InstanceOptions.svg | 2 +- engine/editor/icons/InterpCubic.svg | 2 +- engine/editor/icons/InterpCubicAngle.svg | 2 +- engine/editor/icons/InterpLinear.svg | 2 +- engine/editor/icons/InterpLinearAngle.svg | 2 +- engine/editor/icons/InterpRaw.svg | 2 +- engine/editor/icons/InterpWrapClamp.svg | 2 +- engine/editor/icons/InterpWrapLoop.svg | 2 +- engine/editor/icons/ItemList.svg | 2 +- engine/editor/icons/JoyAxis.svg | 2 +- engine/editor/icons/JoyButton.svg | 2 +- engine/editor/icons/Joypad.svg | 2 +- engine/editor/icons/KeepAspect.svg | 2 +- engine/editor/icons/Key.svg | 2 +- engine/editor/icons/KeyAnimation.svg | 2 +- engine/editor/icons/KeyAudio.svg | 2 +- engine/editor/icons/KeyBezier.svg | 2 +- engine/editor/icons/KeyBezierHandle.svg | 2 +- engine/editor/icons/KeyBezierPoint.svg | 2 +- engine/editor/icons/KeyBezierSelected.svg | 2 +- engine/editor/icons/KeyBlendShape.svg | 2 +- engine/editor/icons/KeyCall.svg | 2 +- engine/editor/icons/KeyEasedSelected.svg | 2 +- engine/editor/icons/KeyInvalid.svg | 2 +- engine/editor/icons/KeyNext.svg | 2 +- engine/editor/icons/KeyPosition.svg | 2 +- engine/editor/icons/KeyRotation.svg | 2 +- engine/editor/icons/KeyScale.svg | 2 +- engine/editor/icons/KeySelected.svg | 2 +- engine/editor/icons/KeyTrackBlendShape.svg | 2 +- engine/editor/icons/KeyTrackPosition.svg | 2 +- engine/editor/icons/KeyTrackRotation.svg | 2 +- engine/editor/icons/KeyTrackScale.svg | 2 +- engine/editor/icons/KeyValue.svg | 2 +- engine/editor/icons/KeyValueEased.svg | 2 +- engine/editor/icons/KeyXPosition.svg | 2 +- engine/editor/icons/KeyXRotation.svg | 2 +- engine/editor/icons/KeyXScale.svg | 2 +- engine/editor/icons/Keyboard.svg | 2 +- engine/editor/icons/KeyboardError.svg | 2 +- engine/editor/icons/KeyboardLabel.svg | 2 +- engine/editor/icons/KeyboardPhysical.svg | 2 +- engine/editor/icons/Label.svg | 2 +- engine/editor/icons/Label3D.svg | 2 +- engine/editor/icons/LabelSettings.svg | 2 +- engine/editor/icons/LightOccluder2D.svg | 2 +- engine/editor/icons/LightmapGI.svg | 2 +- engine/editor/icons/LightmapGIData.svg | 2 +- engine/editor/icons/LightmapProbe.svg | 2 +- engine/editor/icons/Line.svg | 2 +- engine/editor/icons/Line2D.svg | 2 +- engine/editor/icons/LineEdit.svg | 2 +- engine/editor/icons/LinkButton.svg | 2 +- engine/editor/icons/LinkOverlay.svg | 2 +- engine/editor/icons/ListSelect.svg | 2 +- engine/editor/icons/Load.svg | 2 +- engine/editor/icons/LocalVariable.svg | 2 +- engine/editor/icons/Lock.svg | 2 +- engine/editor/icons/LockViewport.svg | 2 +- engine/editor/icons/Logo.svg | 2 +- engine/editor/icons/LookAtModifier3D.svg | 2 +- engine/editor/icons/Loop.svg | 2 +- engine/editor/icons/MainMovieWrite.svg | 2 +- engine/editor/icons/MainPlay.svg | 2 +- engine/editor/icons/MakeFloating.svg | 2 +- engine/editor/icons/MarginContainer.svg | 2 +- engine/editor/icons/Marker.svg | 2 +- engine/editor/icons/Marker2D.svg | 2 +- engine/editor/icons/Marker3D.svg | 2 +- engine/editor/icons/MarkerSelected.svg | 2 +- engine/editor/icons/MatchCase.svg | 2 +- engine/editor/icons/MaterialPreviewCube.svg | 2 +- engine/editor/icons/MaterialPreviewLight1.svg | 2 +- engine/editor/icons/MaterialPreviewLight2.svg | 2 +- engine/editor/icons/MaterialPreviewQuad.svg | 2 +- engine/editor/icons/MaterialPreviewSphere.svg | 2 +- engine/editor/icons/MemberAnnotation.svg | 2 +- engine/editor/icons/MemberConstant.svg | 2 +- engine/editor/icons/MemberConstructor.svg | 2 +- engine/editor/icons/MemberMethod.svg | 2 +- engine/editor/icons/MemberOperator.svg | 2 +- engine/editor/icons/MemberProperty.svg | 2 +- engine/editor/icons/MemberSignal.svg | 2 +- engine/editor/icons/MemberTheme.svg | 2 +- engine/editor/icons/MenuBar.svg | 2 +- engine/editor/icons/MenuButton.svg | 2 +- engine/editor/icons/Mesh.svg | 2 +- engine/editor/icons/MeshInstance2D.svg | 2 +- engine/editor/icons/MeshInstance3D.svg | 2 +- engine/editor/icons/MeshItem.svg | 2 +- engine/editor/icons/MeshLibrary.svg | 2 +- engine/editor/icons/MeshTexture.svg | 2 +- engine/editor/icons/MethodOverride.svg | 2 +- engine/editor/icons/MethodOverrideAndSlot.svg | 2 +- engine/editor/icons/MiniObject.svg | 2 +- engine/editor/icons/MirrorX.svg | 2 +- engine/editor/icons/MirrorY.svg | 2 +- engine/editor/icons/MissingNode.svg | 2 +- engine/editor/icons/MissingResource.svg | 2 +- engine/editor/icons/Modifiers.svg | 2 +- engine/editor/icons/Mouse.svg | 2 +- engine/editor/icons/MoveDown.svg | 2 +- engine/editor/icons/MoveLeft.svg | 2 +- engine/editor/icons/MovePoint.svg | 2 +- engine/editor/icons/MoveRight.svg | 2 +- engine/editor/icons/MoveUp.svg | 2 +- engine/editor/icons/MultiMesh.svg | 2 +- engine/editor/icons/MultiMeshInstance2D.svg | 2 +- engine/editor/icons/MultiMeshInstance3D.svg | 2 +- engine/editor/icons/MultiplayerSpawner.svg | 2 +- .../editor/icons/MultiplayerSynchronizer.svg | 2 +- engine/editor/icons/NavigationAgent2D.svg | 2 +- engine/editor/icons/NavigationAgent3D.svg | 2 +- engine/editor/icons/NavigationLink2D.svg | 2 +- engine/editor/icons/NavigationLink3D.svg | 2 +- engine/editor/icons/NavigationMesh.svg | 2 +- engine/editor/icons/NavigationObstacle2D.svg | 2 +- engine/editor/icons/NavigationObstacle3D.svg | 2 +- engine/editor/icons/NavigationPolygon.svg | 2 +- engine/editor/icons/NavigationRegion2D.svg | 2 +- engine/editor/icons/NavigationRegion3D.svg | 2 +- engine/editor/icons/New.svg | 2 +- engine/editor/icons/NewKey.svg | 2 +- engine/editor/icons/NewRoot.svg | 2 +- engine/editor/icons/NextFrame.svg | 2 +- engine/editor/icons/Nil.svg | 2 +- engine/editor/icons/NinePatchRect.svg | 2 +- engine/editor/icons/Node.svg | 2 +- engine/editor/icons/Node2D.svg | 2 +- engine/editor/icons/Node3D.svg | 2 +- engine/editor/icons/NodeDisabled.svg | 2 +- engine/editor/icons/NodeInfo.svg | 2 +- engine/editor/icons/NodePath.svg | 2 +- engine/editor/icons/NodeWarning.svg | 2 +- engine/editor/icons/NodeWarnings2.svg | 2 +- engine/editor/icons/NodeWarnings3.svg | 2 +- engine/editor/icons/NodeWarnings4Plus.svg | 2 +- engine/editor/icons/NonFavorite.svg | 2 +- engine/editor/icons/Notification.svg | 2 +- engine/editor/icons/NotificationDisabled.svg | 2 +- engine/editor/icons/ORMMaterial3D.svg | 2 +- engine/editor/icons/Object.svg | 2 +- engine/editor/icons/ObjectDisabled.svg | 2 +- engine/editor/icons/Occluder3D.svg | 2 +- engine/editor/icons/OccluderInstance3D.svg | 2 +- engine/editor/icons/OccluderPolygon2D.svg | 2 +- engine/editor/icons/OmniLight3D.svg | 2 +- engine/editor/icons/OneWayTile.svg | 2 +- engine/editor/icons/Onion.svg | 2 +- engine/editor/icons/OptionButton.svg | 2 +- engine/editor/icons/Orientation.svg | 1 + engine/editor/icons/OverbrightIndicator.svg | 2 +- engine/editor/icons/Override.svg | 2 +- engine/editor/icons/PackedByteArray.svg | 2 +- engine/editor/icons/PackedColorArray.svg | 2 +- engine/editor/icons/PackedDataContainer.svg | 2 +- engine/editor/icons/PackedFloat32Array.svg | 2 +- engine/editor/icons/PackedFloat64Array.svg | 2 +- engine/editor/icons/PackedInt32Array.svg | 2 +- engine/editor/icons/PackedInt64Array.svg | 2 +- engine/editor/icons/PackedScene.svg | 2 +- engine/editor/icons/PackedStringArray.svg | 2 +- engine/editor/icons/PackedVector2Array.svg | 2 +- engine/editor/icons/PackedVector3Array.svg | 2 +- engine/editor/icons/PackedVector4Array.svg | 2 +- engine/editor/icons/PageFirst.svg | 2 +- engine/editor/icons/PageLast.svg | 2 +- engine/editor/icons/PageNext.svg | 2 +- engine/editor/icons/PagePrevious.svg | 2 +- engine/editor/icons/Paint.svg | 2 +- engine/editor/icons/Panel.svg | 2 +- engine/editor/icons/PanelContainer.svg | 2 +- engine/editor/icons/Panels1.svg | 2 +- engine/editor/icons/Panels2.svg | 2 +- engine/editor/icons/Panels2Alt.svg | 2 +- engine/editor/icons/Panels3.svg | 2 +- engine/editor/icons/Panels3Alt.svg | 2 +- engine/editor/icons/Panels4.svg | 2 +- engine/editor/icons/PanoramaSkyMaterial.svg | 2 +- engine/editor/icons/Parallax2D.svg | 2 +- engine/editor/icons/ParallaxBackground.svg | 2 +- engine/editor/icons/ParallaxLayer.svg | 2 +- .../editor/icons/ParticleProcessMaterial.svg | 2 +- engine/editor/icons/Path2D.svg | 2 +- engine/editor/icons/Path3D.svg | 2 +- engine/editor/icons/PathFollow2D.svg | 2 +- engine/editor/icons/PathFollow3D.svg | 2 +- engine/editor/icons/Pause.svg | 2 +- engine/editor/icons/Performance.svg | 2 +- engine/editor/icons/PhysicalBone2D.svg | 2 +- engine/editor/icons/PhysicalBone3D.svg | 2 +- .../editor/icons/PhysicalBoneSimulator3D.svg | 2 +- engine/editor/icons/PhysicalSkyMaterial.svg | 2 +- engine/editor/icons/PhysicsMaterial.svg | 2 +- engine/editor/icons/PickerCursor.svg | 2 +- engine/editor/icons/PickerCursorBg.svg | 2 +- engine/editor/icons/PickerShapeCircle.svg | 2 +- engine/editor/icons/PickerShapeRectangle.svg | 2 +- .../icons/PickerShapeRectangleWheel.svg | 2 +- engine/editor/icons/Pin.svg | 2 +- engine/editor/icons/PinJoint2D.svg | 2 +- engine/editor/icons/PinJoint3D.svg | 2 +- engine/editor/icons/PinPressed.svg | 2 +- engine/editor/icons/PingPongLoop.svg | 2 +- engine/editor/icons/PlaceholderMaterial.svg | 2 +- engine/editor/icons/PlaceholderMesh.svg | 2 +- engine/editor/icons/PlaceholderTexture2D.svg | 2 +- engine/editor/icons/PlaceholderTexture3D.svg | 2 +- engine/editor/icons/Plane.svg | 2 +- engine/editor/icons/PlaneMesh.svg | 2 +- engine/editor/icons/Play.svg | 2 +- engine/editor/icons/PlayBackwards.svg | 2 +- engine/editor/icons/PlayCustom.svg | 2 +- engine/editor/icons/PlayOverlay.svg | 2 +- engine/editor/icons/PlayRemote.svg | 2 +- engine/editor/icons/PlayScene.svg | 2 +- engine/editor/icons/PlayStart.svg | 2 +- engine/editor/icons/PlayStartBackwards.svg | 2 +- engine/editor/icons/PlayTravel.svg | 2 +- engine/editor/icons/PluginScript.svg | 2 +- engine/editor/icons/PointLight2D.svg | 2 +- engine/editor/icons/PointMesh.svg | 2 +- engine/editor/icons/Polygon2D.svg | 2 +- engine/editor/icons/PolygonOccluder3D.svg | 2 +- engine/editor/icons/PolygonPathFinder.svg | 2 +- engine/editor/icons/Popup.svg | 2 +- engine/editor/icons/PopupMenu.svg | 2 +- engine/editor/icons/PopupPanel.svg | 2 +- .../icons/PortableCompressedTexture2D.svg | 2 +- engine/editor/icons/PreviewEnvironment.svg | 2 +- engine/editor/icons/PreviewRotate.svg | 2 +- engine/editor/icons/PreviewSun.svg | 2 +- engine/editor/icons/PrismMesh.svg | 2 +- engine/editor/icons/ProceduralSkyMaterial.svg | 2 +- .../editor/icons/ProfilerAutostartWarning.svg | 2 +- engine/editor/icons/Progress1.svg | 2 +- engine/editor/icons/Progress2.svg | 2 +- engine/editor/icons/Progress3.svg | 2 +- engine/editor/icons/Progress4.svg | 2 +- engine/editor/icons/Progress5.svg | 2 +- engine/editor/icons/Progress6.svg | 2 +- engine/editor/icons/Progress7.svg | 2 +- engine/editor/icons/Progress8.svg | 2 +- engine/editor/icons/ProgressBar.svg | 2 +- engine/editor/icons/ProjectIconLoading.svg | 2 +- engine/editor/icons/ProjectList.svg | 2 +- engine/editor/icons/Projection.svg | 2 +- engine/editor/icons/Quad.svg | 2 +- engine/editor/icons/QuadMesh.svg | 2 +- engine/editor/icons/QuadOccluder3D.svg | 2 +- engine/editor/icons/Quaternion.svg | 2 +- engine/editor/icons/RID.svg | 2 +- engine/editor/icons/RandomNumberGenerator.svg | 2 +- engine/editor/icons/Range.svg | 2 +- engine/editor/icons/RangeSliderLeft.svg | 2 +- engine/editor/icons/RangeSliderRight.svg | 2 +- engine/editor/icons/RayCast2D.svg | 2 +- engine/editor/icons/RayCast3D.svg | 2 +- engine/editor/icons/Rect2.svg | 2 +- engine/editor/icons/Rect2i.svg | 2 +- engine/editor/icons/Rectangle.svg | 2 +- engine/editor/icons/RectangleShape2D.svg | 2 +- engine/editor/icons/Redo.svg | 1 + engine/editor/icons/ReferenceRect.svg | 2 +- engine/editor/icons/ReflectionProbe.svg | 2 +- engine/editor/icons/RegionEdit.svg | 2 +- engine/editor/icons/Reload.svg | 2 +- engine/editor/icons/ReloadSmall.svg | 2 +- engine/editor/icons/RemoteTransform2D.svg | 2 +- engine/editor/icons/RemoteTransform3D.svg | 2 +- engine/editor/icons/Remove.svg | 2 +- engine/editor/icons/RemoveInternal.svg | 2 +- engine/editor/icons/Rename.svg | 2 +- engine/editor/icons/Reparent.svg | 2 +- engine/editor/icons/ReparentToNewNode.svg | 2 +- engine/editor/icons/ResourcePreloader.svg | 2 +- engine/editor/icons/RetargetModifier3D.svg | 2 +- engine/editor/icons/ReverseGradient.svg | 2 +- engine/editor/icons/RibbonTrailMesh.svg | 2 +- engine/editor/icons/RichTextEffect.svg | 2 +- engine/editor/icons/RichTextLabel.svg | 2 +- engine/editor/icons/RigidBody2D.svg | 2 +- engine/editor/icons/RigidBody3D.svg | 2 +- engine/editor/icons/RootMotionView.svg | 2 +- engine/editor/icons/RotateLeft.svg | 2 +- engine/editor/icons/RotateRight.svg | 2 +- engine/editor/icons/Ruler.svg | 2 +- engine/editor/icons/SampleLibrary.svg | 2 +- engine/editor/icons/Save.svg | 2 +- engine/editor/icons/SceneUniqueName.svg | 2 +- engine/editor/icons/Script.svg | 2 +- engine/editor/icons/ScriptCreate.svg | 2 +- engine/editor/icons/ScriptCreateDialog.svg | 2 +- engine/editor/icons/ScriptExtend.svg | 2 +- engine/editor/icons/ScriptRemove.svg | 2 +- engine/editor/icons/ScrollContainer.svg | 2 +- engine/editor/icons/Search.svg | 2 +- engine/editor/icons/SegmentShape2D.svg | 2 +- engine/editor/icons/SeparationRayShape2D.svg | 2 +- engine/editor/icons/SeparationRayShape3D.svg | 2 +- engine/editor/icons/Shader.svg | 2 +- engine/editor/icons/ShaderGlobalsOverride.svg | 2 +- engine/editor/icons/ShaderInclude.svg | 2 +- engine/editor/icons/ShaderMaterial.svg | 2 +- engine/editor/icons/ShapeCast2D.svg | 2 +- engine/editor/icons/ShapeCast3D.svg | 2 +- engine/editor/icons/Shortcut.svg | 2 +- engine/editor/icons/ShowInFileSystem.svg | 2 +- engine/editor/icons/Signal.svg | 2 +- engine/editor/icons/Signals.svg | 2 +- engine/editor/icons/SignalsAndGroups.svg | 2 +- engine/editor/icons/Skeleton2D.svg | 2 +- engine/editor/icons/Skeleton3D.svg | 2 +- engine/editor/icons/SkeletonIK3D.svg | 2 +- engine/editor/icons/SkeletonModifier3D.svg | 2 +- engine/editor/icons/SkeletonPreview.svg | 2 +- engine/editor/icons/Sky.svg | 2 +- engine/editor/icons/SliderJoint3D.svg | 2 +- engine/editor/icons/Slot.svg | 2 +- engine/editor/icons/Snap.svg | 2 +- engine/editor/icons/SnapDisable.svg | 2 +- engine/editor/icons/SnapGrid.svg | 2 +- engine/editor/icons/SnapKeys.svg | 2 +- engine/editor/icons/SnapTimeline.svg | 2 +- engine/editor/icons/SoftBody3D.svg | 2 +- engine/editor/icons/Sort.svg | 2 +- engine/editor/icons/SphereMesh.svg | 2 +- engine/editor/icons/SphereOccluder3D.svg | 2 +- engine/editor/icons/SphereShape3D.svg | 2 +- engine/editor/icons/SpinBox.svg | 2 +- engine/editor/icons/SplitContainer.svg | 2 +- engine/editor/icons/SpotLight3D.svg | 2 +- engine/editor/icons/SpringArm3D.svg | 2 +- engine/editor/icons/SpringBoneCollision3D.svg | 2 +- .../icons/SpringBoneCollisionCapsule3D.svg | 2 +- .../icons/SpringBoneCollisionPlane3D.svg | 2 +- .../icons/SpringBoneCollisionSphere3D.svg | 2 +- engine/editor/icons/SpringBoneSimulator3D.svg | 2 +- engine/editor/icons/Sprite2D.svg | 2 +- engine/editor/icons/Sprite3D.svg | 2 +- engine/editor/icons/SpriteFrames.svg | 2 +- engine/editor/icons/SpriteSheet.svg | 2 +- engine/editor/icons/StandardMaterial3D.svg | 2 +- engine/editor/icons/StaticBody2D.svg | 2 +- engine/editor/icons/StaticBody3D.svg | 2 +- engine/editor/icons/StatusError.svg | 2 +- engine/editor/icons/StatusIndicator.svg | 2 +- engine/editor/icons/StatusSuccess.svg | 2 +- engine/editor/icons/StatusWarning.svg | 2 +- engine/editor/icons/Stop.svg | 2 +- engine/editor/icons/Stretch.svg | 2 +- engine/editor/icons/String.svg | 2 +- engine/editor/icons/StringName.svg | 2 +- engine/editor/icons/StyleBoxEmpty.svg | 2 +- engine/editor/icons/StyleBoxFlat.svg | 2 +- engine/editor/icons/StyleBoxGrid.svg | 2 +- engine/editor/icons/StyleBoxLine.svg | 2 +- engine/editor/icons/StyleBoxTexture.svg | 2 +- engine/editor/icons/SubViewport.svg | 2 +- engine/editor/icons/SubViewportContainer.svg | 2 +- engine/editor/icons/SyntaxHighlighter.svg | 2 +- engine/editor/icons/SystemFont.svg | 2 +- engine/editor/icons/TabBar.svg | 2 +- engine/editor/icons/TabContainer.svg | 2 +- engine/editor/icons/Terminal.svg | 2 +- engine/editor/icons/TerrainConnect.svg | 2 +- engine/editor/icons/TerrainMatchCorners.svg | 2 +- .../icons/TerrainMatchCornersAndSides.svg | 2 +- engine/editor/icons/TerrainMatchSides.svg | 2 +- engine/editor/icons/TerrainPath.svg | 2 +- engine/editor/icons/TextEdit.svg | 2 +- engine/editor/icons/TextEditorPlay.svg | 2 +- engine/editor/icons/TextFile.svg | 2 +- engine/editor/icons/TextMesh.svg | 2 +- engine/editor/icons/Texture2D.svg | 2 +- engine/editor/icons/Texture2DArray.svg | 2 +- engine/editor/icons/Texture3D.svg | 2 +- engine/editor/icons/TextureButton.svg | 2 +- .../editor/icons/TexturePreviewChannels.svg | 2 +- engine/editor/icons/TextureProgressBar.svg | 2 +- engine/editor/icons/TextureRect.svg | 2 +- engine/editor/icons/Theme.svg | 2 +- engine/editor/icons/ThemeDeselectAll.svg | 2 +- engine/editor/icons/ThemeRemoveAllItems.svg | 2 +- .../editor/icons/ThemeRemoveCustomItems.svg | 2 +- engine/editor/icons/ThemeSelectAll.svg | 2 +- engine/editor/icons/ThemeSelectFull.svg | 2 +- engine/editor/icons/ThumbnailWait.svg | 2 +- engine/editor/icons/TileChecked.svg | 2 +- engine/editor/icons/TileMap.svg | 2 +- .../editor/icons/TileMapHighlightSelected.svg | 2 +- engine/editor/icons/TileMapLayer.svg | 2 +- engine/editor/icons/TileSelection.svg | 2 +- engine/editor/icons/TileSet.svg | 2 +- engine/editor/icons/TileUnchecked.svg | 2 +- engine/editor/icons/Time.svg | 2 +- engine/editor/icons/TimelineIndicator.svg | 2 +- engine/editor/icons/Timer.svg | 2 +- engine/editor/icons/TitleBarLogo.svg | 2 +- engine/editor/icons/ToolAddNode.svg | 2 +- engine/editor/icons/ToolBoneSelect.svg | 2 +- engine/editor/icons/ToolConnect.svg | 2 +- engine/editor/icons/ToolMove.svg | 2 +- engine/editor/icons/ToolPan.svg | 2 +- engine/editor/icons/ToolRotate.svg | 2 +- engine/editor/icons/ToolScale.svg | 2 +- engine/editor/icons/ToolSelect.svg | 2 +- engine/editor/icons/ToolTriangle.svg | 2 +- engine/editor/icons/Tools.svg | 2 +- engine/editor/icons/TorusMesh.svg | 2 +- engine/editor/icons/TouchScreenButton.svg | 2 +- engine/editor/icons/TrackCapture.svg | 2 +- engine/editor/icons/TrackColor.svg | 2 +- engine/editor/icons/TrackContinuous.svg | 2 +- engine/editor/icons/TrackDiscrete.svg | 2 +- engine/editor/icons/Transform2D.svg | 2 +- engine/editor/icons/Transform3D.svg | 2 +- engine/editor/icons/TransitionEnd.svg | 2 +- engine/editor/icons/TransitionEndAuto.svg | 2 +- engine/editor/icons/TransitionEndAutoBig.svg | 2 +- engine/editor/icons/TransitionEndBig.svg | 2 +- engine/editor/icons/TransitionImmediate.svg | 2 +- .../editor/icons/TransitionImmediateAuto.svg | 2 +- .../icons/TransitionImmediateAutoBig.svg | 2 +- .../editor/icons/TransitionImmediateBig.svg | 2 +- engine/editor/icons/TransitionSync.svg | 2 +- engine/editor/icons/TransitionSyncAuto.svg | 2 +- engine/editor/icons/TransitionSyncAutoBig.svg | 2 +- engine/editor/icons/TransitionSyncBig.svg | 2 +- engine/editor/icons/Translation.svg | 2 +- engine/editor/icons/Tree.svg | 2 +- engine/editor/icons/TripleBar.svg | 2 +- engine/editor/icons/TubeTrailMesh.svg | 2 +- engine/editor/icons/Tween.svg | 2 +- engine/editor/icons/UndoRedo.svg | 2 +- engine/editor/icons/Unfavorite.svg | 2 +- engine/editor/icons/Ungroup.svg | 2 +- engine/editor/icons/Unlinked.svg | 2 +- engine/editor/icons/Unlock.svg | 2 +- engine/editor/icons/UseBlendDisable.svg | 2 +- engine/editor/icons/UseBlendEnable.svg | 2 +- engine/editor/icons/Uv.svg | 2 +- engine/editor/icons/VBoxContainer.svg | 2 +- engine/editor/icons/VFlowContainer.svg | 2 +- engine/editor/icons/VScrollBar.svg | 2 +- engine/editor/icons/VSeparator.svg | 2 +- engine/editor/icons/VSlider.svg | 2 +- engine/editor/icons/VSplitContainer.svg | 2 +- engine/editor/icons/Variant.svg | 2 +- engine/editor/icons/VcsBranches.svg | 2 +- engine/editor/icons/Vector2.svg | 2 +- engine/editor/icons/Vector2i.svg | 2 +- engine/editor/icons/Vector3.svg | 2 +- engine/editor/icons/Vector3i.svg | 2 +- engine/editor/icons/Vector4.svg | 2 +- engine/editor/icons/Vector4i.svg | 2 +- engine/editor/icons/VehicleBody3D.svg | 2 +- engine/editor/icons/VehicleWheel3D.svg | 2 +- engine/editor/icons/VideoStream.svg | 2 +- engine/editor/icons/VideoStreamPlayer.svg | 2 +- engine/editor/icons/VideoStreamTheora.svg | 2 +- engine/editor/icons/Viewport.svg | 2 +- engine/editor/icons/ViewportSpeed.svg | 2 +- engine/editor/icons/ViewportTexture.svg | 2 +- engine/editor/icons/ViewportZoom.svg | 2 +- .../editor/icons/VisibleOnScreenEnabler2D.svg | 2 +- .../editor/icons/VisibleOnScreenEnabler3D.svg | 2 +- .../icons/VisibleOnScreenNotifier2D.svg | 2 +- .../icons/VisibleOnScreenNotifier3D.svg | 2 +- engine/editor/icons/VisualInstance3D.svg | 2 +- engine/editor/icons/VisualShader.svg | 2 +- .../icons/VisualShaderGraphTextureUniform.svg | 2 +- .../icons/VisualShaderNodeBooleanUniform.svg | 2 +- .../icons/VisualShaderNodeColorConstant.svg | 2 +- .../editor/icons/VisualShaderNodeColorOp.svg | 2 +- .../icons/VisualShaderNodeColorUniform.svg | 2 +- .../editor/icons/VisualShaderNodeComment.svg | 2 +- .../editor/icons/VisualShaderNodeCubemap.svg | 2 +- .../icons/VisualShaderNodeCubemapUniform.svg | 2 +- .../icons/VisualShaderNodeCurveTexture.svg | 2 +- .../icons/VisualShaderNodeCurveXYZTexture.svg | 2 +- .../icons/VisualShaderNodeExpression.svg | 2 +- .../icons/VisualShaderNodeFloatFunc.svg | 2 +- .../editor/icons/VisualShaderNodeFloatOp.svg | 2 +- .../icons/VisualShaderNodeFloatUniform.svg | 2 +- .../VisualShaderNodeGlobalExpression.svg | 2 +- engine/editor/icons/VisualShaderNodeInput.svg | 2 +- .../editor/icons/VisualShaderNodeIntFunc.svg | 2 +- engine/editor/icons/VisualShaderNodeIntOp.svg | 2 +- .../icons/VisualShaderNodeIntUniform.svg | 2 +- .../VisualShaderNodeTexture2DArrayUniform.svg | 2 +- .../VisualShaderNodeTexture3DUniform.svg | 2 +- .../icons/VisualShaderNodeTextureUniform.svg | 2 +- ...isualShaderNodeTextureUniformTriplanar.svg | 2 +- .../VisualShaderNodeTransformCompose.svg | 2 +- .../VisualShaderNodeTransformDecompose.svg | 2 +- .../VisualShaderNodeTransformUniform.svg | 2 +- .../VisualShaderNodeTransformVecMult.svg | 2 +- .../icons/VisualShaderNodeVec3Uniform.svg | 2 +- .../icons/VisualShaderNodeVectorCompose.svg | 2 +- .../icons/VisualShaderNodeVectorDecompose.svg | 2 +- .../icons/VisualShaderNodeVectorDistance.svg | 2 +- .../icons/VisualShaderNodeVectorFunc.svg | 2 +- .../icons/VisualShaderNodeVectorLen.svg | 2 +- engine/editor/icons/VisualShaderPort.svg | 2 +- engine/editor/icons/VoxelGI.svg | 2 +- engine/editor/icons/VoxelGIData.svg | 2 +- engine/editor/icons/Warning.svg | 2 +- engine/editor/icons/WarningPattern.svg | 2 +- engine/editor/icons/Window.svg | 2 +- engine/editor/icons/World2D.svg | 2 +- engine/editor/icons/World3D.svg | 2 +- engine/editor/icons/WorldBoundaryShape2D.svg | 2 +- engine/editor/icons/WorldBoundaryShape3D.svg | 2 +- engine/editor/icons/WorldEnvironment.svg | 2 +- engine/editor/icons/X509Certificate.svg | 2 +- engine/editor/icons/XRAnchor3D.svg | 2 +- engine/editor/icons/XRBodyModifier3D.svg | 2 +- engine/editor/icons/XRCamera3D.svg | 2 +- engine/editor/icons/XRController3D.svg | 2 +- engine/editor/icons/XRFaceModifier3D.svg | 2 +- engine/editor/icons/XRHandModifier3D.svg | 2 +- engine/editor/icons/XRNode3D.svg | 2 +- engine/editor/icons/XROrigin3D.svg | 2 +- engine/editor/icons/YSort.svg | 2 +- engine/editor/icons/Zoom.svg | 2 +- engine/editor/icons/ZoomLess.svg | 2 +- engine/editor/icons/ZoomMore.svg | 2 +- engine/editor/icons/ZoomReset.svg | 2 +- engine/editor/icons/bool.svg | 2 +- engine/editor/icons/editor_icons_builders.py | 86 +- engine/editor/icons/float.svg | 2 +- engine/editor/icons/int.svg | 2 +- engine/editor/icons/uint.svg | 2 +- engine/editor/import/3d/collada.cpp | 24 +- engine/editor/import/3d/collada.h | 30 +- .../import/3d/editor_import_collada.cpp | 15 +- .../editor/import/3d/editor_import_collada.h | 7 +- .../post_import_plugin_skeleton_renamer.cpp | 3 - .../3d/post_import_plugin_skeleton_renamer.h | 7 +- ...post_import_plugin_skeleton_rest_fixer.cpp | 3 - .../post_import_plugin_skeleton_rest_fixer.h | 7 +- ...import_plugin_skeleton_track_organizer.cpp | 3 - ...t_import_plugin_skeleton_track_organizer.h | 7 +- .../import/3d/resource_importer_obj.cpp | 22 +- .../editor/import/3d/resource_importer_obj.h | 9 +- .../import/3d/resource_importer_scene.cpp | 146 +- .../import/3d/resource_importer_scene.h | 14 +- .../import/3d/scene_import_settings.cpp | 30 +- .../editor/import/3d/scene_import_settings.h | 13 +- .../import/audio_stream_import_settings.cpp | 10 + .../import/audio_stream_import_settings.h | 5 +- .../import/dynamic_font_import_settings.cpp | 27 +- .../import/dynamic_font_import_settings.h | 5 +- engine/editor/import/editor_import_plugin.cpp | 13 +- engine/editor/import/editor_import_plugin.h | 6 +- .../import/resource_importer_bitmask.cpp | 6 - .../editor/import/resource_importer_bitmask.h | 8 +- .../import/resource_importer_bmfont.cpp | 9 +- .../editor/import/resource_importer_bmfont.h | 7 +- .../resource_importer_csv_translation.cpp | 3 - .../resource_importer_csv_translation.h | 7 +- .../import/resource_importer_dynamic_font.cpp | 18 +- .../import/resource_importer_dynamic_font.h | 7 +- .../editor/import/resource_importer_image.cpp | 3 - .../editor/import/resource_importer_image.h | 7 +- .../import/resource_importer_imagefont.cpp | 4 +- .../import/resource_importer_imagefont.h | 7 +- .../resource_importer_layered_texture.h | 6 +- .../import/resource_importer_shader_file.cpp | 4 +- .../import/resource_importer_shader_file.h | 7 +- .../import/resource_importer_texture.cpp | 15 +- .../editor/import/resource_importer_texture.h | 6 +- .../resource_importer_texture_atlas.cpp | 3 - .../import/resource_importer_texture_atlas.h | 7 +- .../resource_importer_texture_settings.h | 5 +- .../editor/import/resource_importer_wav.cpp | 3 - engine/editor/import/resource_importer_wav.h | 7 +- engine/editor/import_defaults_editor.h | 5 +- engine/editor/import_dock.cpp | 49 +- engine/editor/import_dock.h | 5 +- .../input_event_configuration_dialog.cpp | 4 +- .../editor/input_event_configuration_dialog.h | 5 +- engine/editor/inspector_dock.cpp | 84 +- engine/editor/inspector_dock.h | 6 +- engine/editor/localization_editor.cpp | 19 +- engine/editor/localization_editor.h | 5 +- engine/editor/multi_node_edit.cpp | 24 +- engine/editor/multi_node_edit.h | 9 +- engine/editor/node_dock.cpp | 16 +- engine/editor/node_dock.h | 5 +- .../plugins/abstract_polygon_2d_editor.cpp | 16 +- .../plugins/abstract_polygon_2d_editor.h | 6 +- .../animation_blend_space_1d_editor.cpp | 14 +- .../plugins/animation_blend_space_1d_editor.h | 5 +- .../animation_blend_space_2d_editor.cpp | 21 +- .../plugins/animation_blend_space_2d_editor.h | 5 +- .../animation_blend_tree_editor_plugin.cpp | 12 +- .../animation_blend_tree_editor_plugin.h | 8 +- .../editor/plugins/animation_library_editor.h | 5 +- .../animation_player_editor_plugin.cpp | 30 +- .../plugins/animation_player_editor_plugin.h | 7 +- .../animation_state_machine_editor.cpp | 104 +- .../plugins/animation_state_machine_editor.h | 16 +- .../plugins/animation_tree_editor_plugin.cpp | 3 - .../plugins/animation_tree_editor_plugin.h | 6 +- .../plugins/asset_library_editor_plugin.cpp | 34 +- .../plugins/asset_library_editor_plugin.h | 8 +- .../plugins/audio_stream_editor_plugin.cpp | 2 + .../plugins/audio_stream_editor_plugin.h | 5 +- .../audio_stream_randomizer_editor_plugin.cpp | 2 - .../audio_stream_randomizer_editor_plugin.h | 6 +- .../editor/plugins/bit_map_editor_plugin.cpp | 45 +- engine/editor/plugins/bit_map_editor_plugin.h | 16 +- .../editor/plugins/bone_map_editor_plugin.cpp | 20 +- .../editor/plugins/bone_map_editor_plugin.h | 10 +- .../plugins/camera_2d_editor_plugin.cpp | 165 + .../editor/plugins/camera_2d_editor_plugin.h | 80 + .../plugins/camera_3d_editor_plugin.cpp | 3 - .../editor/plugins/camera_3d_editor_plugin.h | 6 +- .../plugins/canvas_item_editor_plugin.cpp | 157 +- .../plugins/canvas_item_editor_plugin.h | 12 +- engine/editor/plugins/cast_2d_editor_plugin.h | 5 +- .../collision_polygon_2d_editor_plugin.cpp | 2 - .../collision_polygon_2d_editor_plugin.h | 8 +- .../collision_shape_2d_editor_plugin.cpp | 3 - .../collision_shape_2d_editor_plugin.h | 6 +- .../editor/plugins/color_channel_selector.h | 5 +- .../editor/plugins/control_editor_plugin.cpp | 19 +- engine/editor/plugins/control_editor_plugin.h | 8 +- engine/editor/plugins/curve_editor_plugin.cpp | 10 + engine/editor/plugins/curve_editor_plugin.h | 5 +- .../editor/plugins/debugger_editor_plugin.h | 5 +- .../plugins/dedicated_server_export_plugin.h | 5 +- .../plugins/editor_context_menu_plugin.h | 5 +- .../editor/plugins/editor_debugger_plugin.h | 5 +- engine/editor/plugins/editor_plugin.h | 8 +- .../editor/plugins/editor_plugin_settings.h | 5 +- .../editor/plugins/editor_preview_plugins.cpp | 37 +- .../editor/plugins/editor_preview_plugins.h | 19 +- .../editor_resource_conversion_plugin.h | 5 +- .../editor_resource_tooltip_plugins.cpp | 9 +- .../plugins/editor_resource_tooltip_plugins.h | 5 +- engine/editor/plugins/embedded_process.h | 5 +- engine/editor/plugins/font_config_plugin.cpp | 22 +- engine/editor/plugins/font_config_plugin.h | 11 +- engine/editor/plugins/game_view_plugin.cpp | 197 +- engine/editor/plugins/game_view_plugin.h | 37 +- .../plugins/gdextension_export_plugin.h | 5 +- .../gizmos/audio_listener_3d_gizmo_plugin.h | 5 +- .../audio_stream_player_3d_gizmo_plugin.cpp | 124 +- .../audio_stream_player_3d_gizmo_plugin.h | 5 +- .../plugins/gizmos/camera_3d_gizmo_plugin.cpp | 15 +- .../plugins/gizmos/camera_3d_gizmo_plugin.h | 5 +- .../gizmos/collision_object_3d_gizmo_plugin.h | 5 +- .../collision_polygon_3d_gizmo_plugin.h | 5 +- .../collision_shape_3d_gizmo_plugin.cpp | 364 +- .../gizmos/collision_shape_3d_gizmo_plugin.h | 6 +- .../gizmos/cpu_particles_3d_gizmo_plugin.h | 5 +- .../plugins/gizmos/decal_gizmo_plugin.cpp | 3 - .../plugins/gizmos/decal_gizmo_plugin.h | 6 +- .../gizmos/fog_volume_gizmo_plugin.cpp | 3 - .../plugins/gizmos/fog_volume_gizmo_plugin.h | 6 +- .../geometry_instance_3d_gizmo_plugin.cpp | 3 - .../geometry_instance_3d_gizmo_plugin.h | 7 +- .../editor/plugins/gizmos/gizmo_3d_helper.cpp | 41 +- .../editor/plugins/gizmos/gizmo_3d_helper.h | 34 +- .../gizmos/gpu_particles_3d_gizmo_plugin.h | 5 +- ...pu_particles_collision_3d_gizmo_plugin.cpp | 91 +- .../gpu_particles_collision_3d_gizmo_plugin.h | 6 +- .../plugins/gizmos/joint_3d_gizmo_plugin.cpp | 4 +- .../plugins/gizmos/joint_3d_gizmo_plugin.h | 5 +- .../plugins/gizmos/label_3d_gizmo_plugin.cpp | 3 - .../plugins/gizmos/label_3d_gizmo_plugin.h | 7 +- .../plugins/gizmos/light_3d_gizmo_plugin.cpp | 8 +- .../plugins/gizmos/light_3d_gizmo_plugin.h | 5 +- .../gizmos/lightmap_gi_gizmo_plugin.cpp | 8 +- .../plugins/gizmos/lightmap_gi_gizmo_plugin.h | 5 +- .../gizmos/lightmap_probe_gizmo_plugin.cpp | 6 +- .../gizmos/lightmap_probe_gizmo_plugin.h | 5 +- .../plugins/gizmos/marker_3d_gizmo_plugin.h | 5 +- .../gizmos/mesh_instance_3d_gizmo_plugin.cpp | 5 +- .../gizmos/mesh_instance_3d_gizmo_plugin.h | 7 +- .../navigation_link_3d_gizmo_plugin.cpp | 8 +- .../gizmos/navigation_link_3d_gizmo_plugin.h | 5 +- .../navigation_region_3d_gizmo_plugin.cpp | 3 +- .../navigation_region_3d_gizmo_plugin.h | 5 +- .../occluder_instance_3d_gizmo_plugin.h | 5 +- ...particles_3d_emission_shape_gizmo_plugin.h | 5 +- .../gizmos/physics_bone_3d_gizmo_plugin.cpp | 2 +- .../gizmos/physics_bone_3d_gizmo_plugin.h | 5 +- .../plugins/gizmos/ray_cast_3d_gizmo_plugin.h | 5 +- .../gizmos/reflection_probe_gizmo_plugin.cpp | 3 - .../gizmos/reflection_probe_gizmo_plugin.h | 6 +- .../gizmos/shape_cast_3d_gizmo_plugin.h | 5 +- .../gizmos/soft_body_3d_gizmo_plugin.cpp | 2 +- .../gizmos/soft_body_3d_gizmo_plugin.h | 5 +- .../gizmos/spring_arm_3d_gizmo_plugin.h | 5 +- .../gizmos/spring_bone_3d_gizmo_plugin.cpp | 10 +- .../gizmos/spring_bone_3d_gizmo_plugin.h | 5 +- .../gizmos/sprite_base_3d_gizmo_plugin.cpp | 3 - .../gizmos/sprite_base_3d_gizmo_plugin.h | 7 +- .../gizmos/vehicle_body_3d_gizmo_plugin.h | 5 +- ...sible_on_screen_notifier_3d_gizmo_plugin.h | 5 +- .../plugins/gizmos/voxel_gi_gizmo_plugin.cpp | 3 - .../plugins/gizmos/voxel_gi_gizmo_plugin.h | 6 +- ..._particles_collision_sdf_editor_plugin.cpp | 3 - ...pu_particles_collision_sdf_editor_plugin.h | 6 +- .../editor/plugins/gradient_editor_plugin.cpp | 16 +- .../editor/plugins/gradient_editor_plugin.h | 5 +- .../gradient_texture_2d_editor_plugin.cpp | 3 + .../gradient_texture_2d_editor_plugin.h | 5 +- .../plugins/input_event_editor_plugin.h | 5 +- .../light_occluder_2d_editor_plugin.cpp | 2 - .../plugins/light_occluder_2d_editor_plugin.h | 8 +- .../plugins/lightmap_gi_editor_plugin.cpp | 3 - .../plugins/lightmap_gi_editor_plugin.h | 6 +- .../editor/plugins/line_2d_editor_plugin.cpp | 2 - engine/editor/plugins/line_2d_editor_plugin.h | 8 +- .../editor/plugins/material_editor_plugin.cpp | 7 +- .../editor/plugins/material_editor_plugin.h | 5 +- engine/editor/plugins/mesh_editor_plugin.cpp | 4 +- engine/editor/plugins/mesh_editor_plugin.h | 5 +- .../mesh_instance_3d_editor_plugin.cpp | 18 +- .../plugins/mesh_instance_3d_editor_plugin.h | 6 +- .../plugins/mesh_library_editor_plugin.cpp | 6 +- .../plugins/mesh_library_editor_plugin.h | 5 +- .../plugins/multimesh_editor_plugin.cpp | 29 +- .../editor/plugins/multimesh_editor_plugin.h | 6 +- .../navigation_link_2d_editor_plugin.h | 7 +- .../navigation_obstacle_2d_editor_plugin.cpp | 2 - .../navigation_obstacle_2d_editor_plugin.h | 10 +- .../navigation_obstacle_3d_editor_plugin.cpp | 27 +- .../navigation_obstacle_3d_editor_plugin.h | 5 +- .../navigation_polygon_editor_plugin.cpp | 2 +- .../navigation_polygon_editor_plugin.h | 5 +- .../editor/plugins/node_3d_editor_gizmos.cpp | 71 +- engine/editor/plugins/node_3d_editor_gizmos.h | 7 +- .../editor/plugins/node_3d_editor_plugin.cpp | 1247 +- engine/editor/plugins/node_3d_editor_plugin.h | 57 +- .../occluder_instance_3d_editor_plugin.cpp | 3 - .../occluder_instance_3d_editor_plugin.h | 6 +- .../plugins/packed_scene_editor_plugin.cpp | 2 +- .../plugins/packed_scene_editor_plugin.h | 5 +- ...packed_scene_translation_parser_plugin.cpp | 2 +- .../packed_scene_translation_parser_plugin.h | 5 +- .../parallax_background_editor_plugin.cpp | 2 + .../parallax_background_editor_plugin.h | 5 +- ...article_process_material_editor_plugin.cpp | 1 + .../particle_process_material_editor_plugin.h | 5 +- .../plugins/particles_editor_plugin.cpp | 34 +- .../editor/plugins/particles_editor_plugin.h | 15 +- .../editor/plugins/path_2d_editor_plugin.cpp | 39 +- engine/editor/plugins/path_2d_editor_plugin.h | 10 +- .../editor/plugins/path_3d_editor_plugin.cpp | 70 +- engine/editor/plugins/path_3d_editor_plugin.h | 10 +- .../physical_bone_3d_editor_plugin.cpp | 2 - .../plugins/physical_bone_3d_editor_plugin.h | 8 +- .../editor/plugins/plugin_config_dialog.cpp | 13 +- engine/editor/plugins/plugin_config_dialog.h | 6 +- .../plugins/polygon_2d_editor_plugin.cpp | 26 +- .../editor/plugins/polygon_2d_editor_plugin.h | 5 +- .../plugins/polygon_3d_editor_plugin.cpp | 21 +- .../editor/plugins/polygon_3d_editor_plugin.h | 6 +- .../resource_preloader_editor_plugin.cpp | 6 +- .../resource_preloader_editor_plugin.h | 6 +- .../plugins/root_motion_editor_plugin.cpp | 2 + .../plugins/root_motion_editor_plugin.h | 5 +- .../editor/plugins/script_editor_plugin.cpp | 200 +- engine/editor/plugins/script_editor_plugin.h | 19 +- engine/editor/plugins/script_text_editor.cpp | 110 +- engine/editor/plugins/script_text_editor.h | 8 +- engine/editor/plugins/shader/shader_editor.h | 6 +- .../editor/plugins/shader_editor_plugin.cpp | 156 +- engine/editor/plugins/shader_editor_plugin.h | 16 +- .../plugins/shader_file_editor_plugin.cpp | 5 +- .../plugins/shader_file_editor_plugin.h | 6 +- .../plugins/skeleton_2d_editor_plugin.cpp | 5 +- .../plugins/skeleton_2d_editor_plugin.h | 6 +- .../plugins/skeleton_3d_editor_plugin.cpp | 24 +- .../plugins/skeleton_3d_editor_plugin.h | 5 +- .../plugins/skeleton_ik_3d_editor_plugin.cpp | 2 - .../plugins/skeleton_ik_3d_editor_plugin.h | 6 +- .../plugins/sprite_2d_editor_plugin.cpp | 8 +- .../editor/plugins/sprite_2d_editor_plugin.h | 6 +- .../plugins/sprite_frames_editor_plugin.cpp | 96 +- .../plugins/sprite_frames_editor_plugin.h | 8 +- .../plugins/style_box_editor_plugin.cpp | 2 + .../editor/plugins/style_box_editor_plugin.h | 5 +- .../sub_viewport_preview_editor_plugin.h | 5 +- engine/editor/plugins/text_editor.cpp | 8 +- engine/editor/plugins/text_editor.h | 7 +- engine/editor/plugins/text_shader_editor.cpp | 36 +- engine/editor/plugins/text_shader_editor.h | 9 +- .../editor/plugins/texture_3d_editor_plugin.h | 5 +- .../editor/plugins/texture_editor_plugin.cpp | 5 + engine/editor/plugins/texture_editor_plugin.h | 5 +- .../plugins/texture_layered_editor_plugin.cpp | 3 - .../plugins/texture_layered_editor_plugin.h | 6 +- .../plugins/texture_region_editor_plugin.cpp | 16 +- .../plugins/texture_region_editor_plugin.h | 5 +- engine/editor/plugins/theme_editor_plugin.cpp | 58 +- engine/editor/plugins/theme_editor_plugin.h | 5 +- .../editor/plugins/theme_editor_preview.cpp | 2 +- engine/editor/plugins/theme_editor_preview.h | 5 +- .../plugins/tiles/atlas_merging_dialog.h | 5 +- .../editor/plugins/tiles/tile_atlas_view.cpp | 1 + engine/editor/plugins/tiles/tile_atlas_view.h | 5 +- .../plugins/tiles/tile_data_editors.cpp | 55 +- .../editor/plugins/tiles/tile_data_editors.h | 5 +- .../plugins/tiles/tile_map_layer_editor.cpp | 97 +- .../plugins/tiles/tile_map_layer_editor.h | 8 +- .../tiles/tile_proxies_manager_dialog.h | 5 +- .../tiles/tile_set_atlas_source_editor.cpp | 59 +- .../tiles/tile_set_atlas_source_editor.h | 7 +- .../editor/plugins/tiles/tile_set_editor.cpp | 13 +- engine/editor/plugins/tiles/tile_set_editor.h | 9 +- ...le_set_scenes_collection_source_editor.cpp | 8 +- ...tile_set_scenes_collection_source_editor.h | 5 +- .../plugins/tiles/tiles_editor_plugin.cpp | 10 +- .../plugins/tiles/tiles_editor_plugin.h | 5 +- .../plugins/tool_button_editor_plugin.h | 5 +- .../plugins/version_control_editor_plugin.cpp | 30 +- .../plugins/version_control_editor_plugin.h | 5 +- .../plugins/visual_shader_editor_plugin.cpp | 137 +- .../plugins/visual_shader_editor_plugin.h | 19 +- .../editor/plugins/voxel_gi_editor_plugin.cpp | 3 - .../editor/plugins/voxel_gi_editor_plugin.h | 6 +- engine/editor/pot_generator.cpp | 3 - engine/editor/pot_generator.h | 6 +- engine/editor/progress_dialog.h | 7 +- engine/editor/project_converter_3_to_4.cpp | 12 +- engine/editor/project_converter_3_to_4.h | 5 +- engine/editor/project_manager.cpp | 79 +- engine/editor/project_manager.h | 11 +- .../editor/project_manager/project_dialog.cpp | 17 +- .../editor/project_manager/project_dialog.h | 5 +- .../editor/project_manager/project_list.cpp | 153 +- engine/editor/project_manager/project_list.h | 15 +- engine/editor/project_manager/project_tag.cpp | 3 +- engine/editor/project_manager/project_tag.h | 5 +- .../project_manager/quick_settings_dialog.cpp | 46 +- .../project_manager/quick_settings_dialog.h | 8 +- engine/editor/project_settings_editor.cpp | 23 +- engine/editor/project_settings_editor.h | 8 +- engine/editor/project_upgrade_tool.cpp | 135 + ..._upgrade_tool.h => project_upgrade_tool.h} | 52 +- engine/editor/property_selector.cpp | 29 +- engine/editor/property_selector.h | 5 +- engine/editor/register_editor_types.cpp | 6 +- engine/editor/register_editor_types.h | 5 +- engine/editor/register_exporters.h | 5 +- engine/editor/rename_dialog.cpp | 11 +- engine/editor/rename_dialog.h | 5 +- engine/editor/renames_map_3_to_4.h | 5 +- engine/editor/reparent_dialog.cpp | 3 - engine/editor/reparent_dialog.h | 6 +- engine/editor/run_instances_dialog.cpp | 3 + engine/editor/run_instances_dialog.h | 5 +- engine/editor/scene_create_dialog.cpp | 7 +- engine/editor/scene_create_dialog.h | 5 +- engine/editor/scene_tree_dock.cpp | 143 +- engine/editor/scene_tree_dock.h | 6 +- engine/editor/script_create_dialog.cpp | 42 +- engine/editor/script_create_dialog.h | 7 +- engine/editor/shader_create_dialog.cpp | 13 +- engine/editor/shader_create_dialog.h | 5 +- engine/editor/shader_globals_editor.h | 5 +- engine/editor/surface_upgrade_tool.cpp | 202 - engine/editor/template_builders.py | 69 +- engine/editor/themes/SCsub | 11 +- engine/editor/themes/editor_color_map.h | 5 +- engine/editor/themes/editor_fonts.cpp | 38 +- engine/editor/themes/editor_fonts.h | 5 +- engine/editor/themes/editor_icons.cpp | 69 +- engine/editor/themes/editor_icons.h | 5 +- engine/editor/themes/editor_scale.h | 5 +- engine/editor/themes/editor_theme.h | 5 +- engine/editor/themes/editor_theme_builders.py | 34 +- engine/editor/themes/editor_theme_manager.cpp | 61 +- engine/editor/themes/editor_theme_manager.h | 7 +- engine/editor/translations/editor/ar.po | 12 +- engine/editor/translations/editor/ca.po | 84 +- engine/editor/translations/editor/cs.po | 53 +- engine/editor/translations/editor/de.po | 409 +- engine/editor/translations/editor/es.po | 84 +- engine/editor/translations/editor/es_AR.po | 1520 +- engine/editor/translations/editor/fa.po | 2608 +- engine/editor/translations/editor/fi.po | 31 +- engine/editor/translations/editor/fr.po | 244 +- engine/editor/translations/editor/ga.po | 12 +- engine/editor/translations/editor/id.po | 34 +- engine/editor/translations/editor/it.po | 1920 +- engine/editor/translations/editor/ja.po | 46 +- engine/editor/translations/editor/ka.po | 13 +- engine/editor/translations/editor/ko.po | 12 +- engine/editor/translations/editor/lv.po | 932 +- engine/editor/translations/editor/nl.po | 6 +- engine/editor/translations/editor/pl.po | 71 +- engine/editor/translations/editor/pt.po | 12 +- engine/editor/translations/editor/pt_BR.po | 5672 ++- engine/editor/translations/editor/ro.po | 10 +- engine/editor/translations/editor/ru.po | 875 +- engine/editor/translations/editor/sv.po | 176 +- engine/editor/translations/editor/tok.po | 4076 ++ engine/editor/translations/editor/tr.po | 109 +- engine/editor/translations/editor/uk.po | 302 +- engine/editor/translations/editor/vi.po | 507 +- engine/editor/translations/editor/zh_CN.po | 74 +- engine/editor/translations/editor/zh_TW.po | 12 +- .../translations/extractable/extractable.pot | 4 + engine/editor/translations/extractable/fr.po | 3 + engine/editor/translations/properties/cs.po | 42 +- engine/editor/translations/properties/de.po | 132 +- engine/editor/translations/properties/es.po | 198 +- engine/editor/translations/properties/et.po | 36 +- engine/editor/translations/properties/fa.po | 62 +- engine/editor/translations/properties/fr.po | 36 +- engine/editor/translations/properties/ga.po | 42 +- engine/editor/translations/properties/id.po | 36 +- engine/editor/translations/properties/it.po | 704 +- engine/editor/translations/properties/ja.po | 36 +- engine/editor/translations/properties/ka.po | 36 +- engine/editor/translations/properties/ko.po | 36 +- engine/editor/translations/properties/pl.po | 1126 +- engine/editor/translations/properties/pt.po | 36 +- .../editor/translations/properties/pt_BR.po | 2156 +- engine/editor/translations/properties/ru.po | 170 +- engine/editor/translations/properties/ta.po | 36 +- engine/editor/translations/properties/tr.po | 273 +- engine/editor/translations/properties/uk.po | 280 +- engine/editor/translations/properties/vi.po | 12 +- .../editor/translations/properties/zh_CN.po | 280 +- .../editor/translations/properties/zh_TW.po | 36 +- engine/editor/uid_upgrade_tool.cpp | 126 - engine/editor/window_wrapper.cpp | 2 +- engine/editor/window_wrapper.h | 5 +- engine/gles3_builders.py | 610 +- engine/glsl_builders.py | 116 +- engine/icon.svg | 2 +- engine/icon_outlined.svg | 2 +- engine/logo.svg | 2 +- engine/logo_outlined.svg | 2 +- engine/main/SCsub | 3 - engine/main/main.cpp | 462 +- engine/main/main.h | 6 +- engine/main/main_builders.py | 70 +- engine/main/main_timer_sync.h | 5 +- engine/main/performance.cpp | 247 +- engine/main/performance.h | 25 +- engine/main/steam_tracker.h | 5 +- engine/methods.py | 380 +- engine/misc/dist/document_icons/gdscript.svg | 2 +- .../document_icons/gdscript_extra_small.svg | 2 +- .../dist/document_icons/gdscript_small.svg | 2 +- engine/misc/dist/document_icons/project.svg | 2 +- .../document_icons/project_extra_small.svg | 2 +- .../dist/document_icons/project_small.svg | 2 +- engine/misc/dist/document_icons/resource.svg | 2 +- .../document_icons/resource_extra_small.svg | 2 +- .../dist/document_icons/resource_small.svg | 2 +- engine/misc/dist/document_icons/scene.svg | 2 +- .../dist/document_icons/scene_extra_small.svg | 2 +- .../misc/dist/document_icons/scene_small.svg | 2 +- engine/misc/dist/document_icons/shader.svg | 2 +- .../document_icons/shader_extra_small.svg | 2 +- .../misc/dist/document_icons/shader_small.svg | 2 +- engine/misc/dist/html/logo.svg | 2 +- engine/misc/dist/icon_console.svg | 2 +- engine/misc/dist/ios_xcode/godot_ios/dummy.h | 2 + .../dist/linux/org.godotengine.Godot.desktop | 1 - .../dist/macos_tools.app/Contents/Info.plist | 4 +- engine/misc/dist/windows/godot.iss | 2 +- engine/misc/error_suppressions/tsan.txt | 3 +- ...xpected => 4.3-stable_4.4-stable.expected} | 10 +- .../4.4-stable.expected | 50 + engine/misc/msvs/nmake.substitution.props | 19 + engine/misc/msvs/props.template | 5 +- engine/misc/msvs/vcxproj.template | 13 +- engine/misc/scripts/char_range_fetch.py | 135 + engine/misc/scripts/header_guards.py | 134 +- .../misc/scripts/install_d3d12_sdk_windows.py | 12 +- engine/misc/scripts/make_tarball.sh | 2 +- engine/misc/scripts/purge_cache.py | 47 + engine/misc/scripts/ucaps_fetch.py | 5 +- engine/misc/utility/color.py | 166 +- engine/misc/utility/svgo.config.mjs | 4 + engine/modules/SCsub | 32 +- engine/modules/astcenc/SCsub | 2 +- .../modules/astcenc/image_compress_astcenc.h | 5 +- engine/modules/astcenc/register_types.h | 5 +- engine/modules/basis_universal/SCsub | 12 +- .../basis_universal/image_compress_basisu.cpp | 3 +- .../basis_universal/image_compress_basisu.h | 5 +- .../modules/basis_universal/register_types.h | 5 +- .../modules/bcdec/image_decompress_bcdec.cpp | 16 +- engine/modules/bcdec/image_decompress_bcdec.h | 5 +- engine/modules/bcdec/register_types.h | 5 +- engine/modules/betsy/bc6h.glsl | 36 +- engine/modules/betsy/betsy_bc1.h | 5 +- engine/modules/betsy/image_compress_betsy.cpp | 77 +- engine/modules/betsy/image_compress_betsy.h | 5 +- engine/modules/betsy/register_types.h | 5 +- engine/modules/bmp/image_loader_bmp.h | 5 +- engine/modules/bmp/register_types.h | 5 +- engine/modules/camera/buffer_decoder.h | 5 +- engine/modules/camera/camera_feed_linux.cpp | 6 +- engine/modules/camera/camera_feed_linux.h | 19 +- engine/modules/camera/camera_linux.cpp | 24 +- engine/modules/camera/camera_linux.h | 9 +- engine/modules/camera/camera_macos.h | 10 +- engine/modules/camera/camera_macos.mm | 28 +- engine/modules/camera/camera_win.h | 5 +- engine/modules/camera/register_types.h | 5 +- engine/modules/csg/SCsub | 2 +- engine/modules/csg/csg.h | 5 +- engine/modules/csg/csg_shape.cpp | 84 +- engine/modules/csg/csg_shape.h | 18 +- engine/modules/csg/doc_classes/CSGShape3D.xml | 10 +- engine/modules/csg/editor/csg_gizmos.cpp | 13 +- engine/modules/csg/editor/csg_gizmos.h | 10 +- engine/modules/csg/icons/CSGBox3D.svg | 2 +- engine/modules/csg/icons/CSGCapsule3D.svg | 2 +- engine/modules/csg/icons/CSGCombiner3D.svg | 2 +- engine/modules/csg/icons/CSGCylinder3D.svg | 2 +- engine/modules/csg/icons/CSGMesh3D.svg | 2 +- engine/modules/csg/icons/CSGPolygon3D.svg | 2 +- engine/modules/csg/icons/CSGSphere3D.svg | 2 +- engine/modules/csg/icons/CSGTorus3D.svg | 2 +- engine/modules/csg/register_types.cpp | 2 + engine/modules/csg/register_types.h | 5 +- engine/modules/csg/tests/test_csg.h | 5 +- engine/modules/cvtt/SCsub | 2 +- engine/modules/cvtt/image_compress_cvtt.cpp | 70 +- engine/modules/cvtt/image_compress_cvtt.h | 5 +- engine/modules/cvtt/register_types.h | 5 +- engine/modules/dds/dds_enums.h | 203 + engine/modules/dds/image_saver_dds.cpp | 487 + engine/modules/dds/image_saver_dds.h | 36 + engine/modules/dds/register_types.cpp | 21 +- engine/modules/dds/register_types.h | 5 +- engine/modules/dds/tests/test_dds.h | 161 + engine/modules/dds/texture_loader_dds.cpp | 746 +- engine/modules/dds/texture_loader_dds.h | 6 +- engine/modules/enet/SCsub | 2 +- engine/modules/enet/enet_connection.cpp | 10 +- engine/modules/enet/enet_connection.h | 5 +- engine/modules/enet/enet_multiplayer_peer.cpp | 4 +- engine/modules/enet/enet_multiplayer_peer.h | 5 +- engine/modules/enet/enet_packet_peer.h | 5 +- engine/modules/enet/register_types.h | 5 +- engine/modules/etcpak/SCsub | 2 +- engine/modules/etcpak/image_compress_etcpak.h | 5 +- .../modules/etcpak/image_decompress_etcpak.h | 5 +- engine/modules/etcpak/register_types.h | 5 +- engine/modules/fbx/SCsub | 2 +- .../editor/editor_scene_importer_fbx2gltf.cpp | 4 - .../editor/editor_scene_importer_fbx2gltf.h | 9 +- .../fbx/editor/editor_scene_importer_ufbx.cpp | 4 - .../fbx/editor/editor_scene_importer_ufbx.h | 8 +- engine/modules/fbx/fbx_document.cpp | 14 +- engine/modules/fbx/fbx_document.h | 5 +- engine/modules/fbx/fbx_state.h | 5 +- engine/modules/fbx/register_types.cpp | 5 - engine/modules/fbx/register_types.h | 5 +- engine/modules/freetype/SCsub | 6 +- engine/modules/freetype/register_types.h | 5 +- .../gdscript/doc_classes/@GDScript.xml | 4 +- .../gdscript/editor/gdscript_docgen.cpp | 12 +- .../modules/gdscript/editor/gdscript_docgen.h | 5 +- .../gdscript/editor/gdscript_highlighter.cpp | 17 +- .../gdscript/editor/gdscript_highlighter.h | 5 +- .../gdscript_translation_parser_plugin.h | 5 +- .../script_templates/EditorPlugin/plugin.gd | 10 + engine/modules/gdscript/gdscript.cpp | 110 +- engine/modules/gdscript/gdscript.h | 9 +- engine/modules/gdscript/gdscript_analyzer.cpp | 60 +- engine/modules/gdscript/gdscript_analyzer.h | 5 +- .../modules/gdscript/gdscript_byte_codegen.h | 5 +- engine/modules/gdscript/gdscript_cache.cpp | 7 +- engine/modules/gdscript/gdscript_cache.h | 7 +- engine/modules/gdscript/gdscript_codegen.h | 5 +- engine/modules/gdscript/gdscript_compiler.cpp | 9 +- engine/modules/gdscript/gdscript_compiler.h | 5 +- engine/modules/gdscript/gdscript_editor.cpp | 256 +- engine/modules/gdscript/gdscript_function.h | 12 +- .../gdscript/gdscript_lambda_callable.cpp | 4 +- .../gdscript/gdscript_lambda_callable.h | 5 +- engine/modules/gdscript/gdscript_parser.cpp | 64 +- engine/modules/gdscript/gdscript_parser.h | 19 +- .../modules/gdscript/gdscript_rpc_callable.h | 5 +- .../modules/gdscript/gdscript_tokenizer.cpp | 10 +- engine/modules/gdscript/gdscript_tokenizer.h | 5 +- .../gdscript/gdscript_tokenizer_buffer.cpp | 2 +- .../gdscript/gdscript_tokenizer_buffer.h | 5 +- .../gdscript/gdscript_utility_callable.h | 5 +- .../gdscript/gdscript_utility_functions.cpp | 4 +- .../gdscript/gdscript_utility_functions.h | 5 +- engine/modules/gdscript/gdscript_vm.cpp | 13 +- engine/modules/gdscript/gdscript_warning.cpp | 2 +- engine/modules/gdscript/gdscript_warning.h | 7 +- engine/modules/gdscript/icons/GDScript.svg | 2 +- .../gdscript/icons/GDScriptInternal.svg | 2 +- .../gdscript_extend_parser.cpp | 150 +- .../language_server/gdscript_extend_parser.h | 51 +- .../gdscript_language_protocol.cpp | 57 +- .../gdscript_language_protocol.h | 10 +- .../gdscript_language_server.h | 5 +- .../gdscript_text_document.cpp | 146 +- .../language_server/gdscript_text_document.h | 21 +- .../language_server/gdscript_workspace.cpp | 158 +- .../language_server/gdscript_workspace.h | 37 +- .../gdscript/language_server/godot_lsp.h | 68 +- engine/modules/gdscript/register_types.cpp | 8 +- engine/modules/gdscript/register_types.h | 5 +- .../gdscript/tests/gdscript_test_runner.cpp | 2 +- .../gdscript/tests/gdscript_test_runner.h | 5 +- .../tests/gdscript_test_runner_suite.h | 15 +- .../argument_options/play_inferred.gd | 2 + .../completion/argument_options/play_typed.gd | 2 + .../argument_options/play_untyped.gd | 2 + .../common/invalid_super_call_1.cfg | 5 + .../completion/common/invalid_super_call_1.gd | 7 + .../common/invalid_super_call_2.cfg | 5 + .../completion/common/invalid_super_call_2.gd | 7 + .../completion/get_node/literal/dollar.gd | 2 +- .../completion/get_node/literal/percent.gd | 2 +- .../local_inferred.cfg} | 0 .../local_inferred.gd} | 0 .../class_local_inferred_scene.cfg} | 0 .../class_local_inferred_scene.gd} | 0 .../native_local_inferred_scene.cfg} | 0 .../native_local_inferred_scene.gd} | 0 .../member_inferred.cfg} | 0 .../member_inferred.gd} | 0 .../class_member_inferred_scene.cfg} | 0 .../class_member_inferred_scene.gd} | 2 +- .../native_member_inferred_scene.cfg} | 0 .../native_member_inferred_scene.gd} | 2 +- .../member_scene/class_member_scene.gd | 2 +- .../member_scene/native_member_scene.gd | 2 +- .../native_member_typehint_scene.gd | 2 +- .../class_member_typehint_scene_broad.gd | 2 +- .../native_member_typehint_scene_broad.gd | 2 +- ...lass_member_typehint_scene_incompatible.gd | 2 +- ...tive_member_typehint_scene_incompatible.gd | 2 +- .../builtin_complete_braces.cfg | 8 + .../builtin_complete_braces.gd | 8 + .../builtin_incomplete_braces.cfg | 8 + .../builtin_incomplete_braces.gd | 8 + .../local_method_callable_arg_0.cfg | 8 + .../local_method_callable_arg_0.gd | 9 + .../local_method_callable_arg_1.cfg | 8 + .../local_method_callable_arg_1.gd | 9 + .../local_method_variant_arg_0.cfg | 8 + .../local_method_variant_arg_0.gd | 9 + .../native.cfg | 8 + .../native.gd | 8 + .../types/local/{infered.cfg => inferred.cfg} | 0 .../types/local/{infered.gd => inferred.gd} | 0 .../member/{infered.cfg => inferred.cfg} | 0 .../types/member/{infered.gd => inferred.gd} | 0 .../scripts/lsp/first_line_class_name.gd | 5 + .../reload_suspended_function.notest.gd | 12 + .../errors/reload_suspended_function.out | 2 + ...reload_suspended_function_helper.notest.gd | 3 + .../runtime/features/callv_readonly_array.gd | 26 + .../runtime/features/callv_readonly_array.out | 11 + .../modules/gdscript/tests/test_completion.h | 9 +- .../modules/gdscript/tests/test_gdscript.cpp | 3 +- engine/modules/gdscript/tests/test_gdscript.h | 5 +- engine/modules/gdscript/tests/test_lsp.h | 97 +- engine/modules/glslang/SCsub | 6 +- engine/modules/glslang/register_types.h | 5 +- .../EditorSceneFormatImporterBlend.xml | 2 +- .../modules/gltf/doc_classes/GLTFAccessor.xml | 4 +- engine/modules/gltf/doc_classes/GLTFLight.xml | 5 +- engine/modules/gltf/doc_classes/GLTFNode.xml | 2 +- .../doc_classes/GLTFObjectModelProperty.xml | 2 +- .../gltf/doc_classes/GLTFPhysicsBody.xml | 4 +- .../gltf/doc_classes/GLTFPhysicsShape.xml | 14 +- engine/modules/gltf/doc_classes/GLTFState.xml | 4 +- .../editor/editor_import_blend_runner.cpp | 18 +- .../gltf/editor/editor_import_blend_runner.h | 9 +- .../editor_scene_exporter_gltf_plugin.cpp | 4 - .../editor_scene_exporter_gltf_plugin.h | 9 +- .../editor_scene_exporter_gltf_settings.h | 9 +- .../editor/editor_scene_importer_blend.cpp | 8 +- .../gltf/editor/editor_scene_importer_blend.h | 11 +- .../editor/editor_scene_importer_gltf.cpp | 4 - .../gltf/editor/editor_scene_importer_gltf.h | 9 +- engine/modules/gltf/extensions/SCsub | 3 +- .../gltf/extensions/gltf_document_extension.h | 5 +- ...document_extension_convert_importer_mesh.h | 5 +- .../gltf_document_extension_texture_ktx.h | 5 +- .../gltf_document_extension_texture_webp.h | 5 +- engine/modules/gltf/extensions/gltf_light.cpp | 48 +- engine/modules/gltf/extensions/gltf_light.h | 9 +- .../modules/gltf/extensions/gltf_spec_gloss.h | 5 +- .../physics/gltf_document_extension_physics.h | 5 +- .../extensions/physics/gltf_physics_body.h | 5 +- .../extensions/physics/gltf_physics_shape.h | 5 +- engine/modules/gltf/gltf_defines.h | 5 +- engine/modules/gltf/gltf_document.cpp | 164 +- engine/modules/gltf/gltf_document.h | 18 +- engine/modules/gltf/gltf_state.h | 5 +- engine/modules/gltf/gltf_template_convert.h | 10 +- engine/modules/gltf/register_types.cpp | 17 +- engine/modules/gltf/register_types.h | 5 +- engine/modules/gltf/skin_tool.cpp | 5 +- engine/modules/gltf/skin_tool.h | 5 +- .../modules/gltf/structures/gltf_accessor.h | 5 +- .../modules/gltf/structures/gltf_animation.h | 5 +- .../gltf/structures/gltf_buffer_view.h | 5 +- engine/modules/gltf/structures/gltf_camera.h | 5 +- engine/modules/gltf/structures/gltf_mesh.h | 5 +- engine/modules/gltf/structures/gltf_node.h | 5 +- .../structures/gltf_object_model_property.h | 5 +- .../modules/gltf/structures/gltf_skeleton.h | 5 +- engine/modules/gltf/structures/gltf_skin.cpp | 17 +- engine/modules/gltf/structures/gltf_skin.h | 5 +- engine/modules/gltf/structures/gltf_texture.h | 5 +- .../gltf/structures/gltf_texture_sampler.h | 5 +- engine/modules/gltf/tests/test_gltf.h | 16 +- engine/modules/gltf/tests/test_gltf_extras.h | 5 +- engine/modules/gltf/tests/test_gltf_images.h | 5 +- engine/modules/godot_physics_2d/config.py | 2 +- .../modules/godot_physics_2d/godot_area_2d.h | 5 +- .../godot_physics_2d/godot_area_pair_2d.h | 5 +- .../godot_physics_2d/godot_body_2d.cpp | 4 +- .../modules/godot_physics_2d/godot_body_2d.h | 6 +- .../godot_body_direct_state_2d.h | 5 +- .../godot_physics_2d/godot_body_pair_2d.cpp | 4 +- .../godot_physics_2d/godot_body_pair_2d.h | 5 +- .../godot_physics_2d/godot_broad_phase_2d.h | 5 +- .../godot_broad_phase_2d_bvh.h | 5 +- .../godot_collision_object_2d.h | 5 +- .../godot_collision_solver_2d.h | 5 +- .../godot_collision_solver_2d_sat.cpp | 2 +- .../godot_collision_solver_2d_sat.h | 5 +- .../godot_physics_2d/godot_constraint_2d.h | 5 +- .../godot_physics_2d/godot_joints_2d.h | 5 +- .../godot_physics_server_2d.h | 5 +- .../godot_physics_2d/godot_shape_2d.cpp | 4 +- .../modules/godot_physics_2d/godot_shape_2d.h | 5 +- .../modules/godot_physics_2d/godot_space_2d.h | 5 +- .../modules/godot_physics_2d/godot_step_2d.h | 5 +- .../modules/godot_physics_2d/register_types.h | 5 +- engine/modules/godot_physics_3d/config.py | 2 +- engine/modules/godot_physics_3d/gjk_epa.h | 5 +- .../modules/godot_physics_3d/godot_area_3d.h | 5 +- .../godot_physics_3d/godot_area_pair_3d.h | 5 +- .../godot_physics_3d/godot_body_3d.cpp | 2 +- .../modules/godot_physics_3d/godot_body_3d.h | 6 +- .../godot_body_direct_state_3d.h | 5 +- .../godot_physics_3d/godot_body_pair_3d.cpp | 4 +- .../godot_physics_3d/godot_body_pair_3d.h | 5 +- .../godot_physics_3d/godot_broad_phase_3d.h | 5 +- .../godot_broad_phase_3d_bvh.h | 5 +- .../godot_collision_object_3d.h | 5 +- .../godot_collision_solver_3d.cpp | 8 +- .../godot_collision_solver_3d.h | 5 +- .../godot_collision_solver_3d_sat.cpp | 23 +- .../godot_collision_solver_3d_sat.h | 5 +- .../godot_physics_3d/godot_constraint_3d.h | 5 +- .../modules/godot_physics_3d/godot_joint_3d.h | 9 +- .../godot_physics_server_3d.h | 5 +- .../godot_physics_3d/godot_shape_3d.cpp | 56 +- .../modules/godot_physics_3d/godot_shape_3d.h | 13 +- .../godot_physics_3d/godot_soft_body_3d.cpp | 4 +- .../godot_physics_3d/godot_soft_body_3d.h | 5 +- .../modules/godot_physics_3d/godot_space_3d.h | 5 +- .../modules/godot_physics_3d/godot_step_3d.h | 5 +- .../joints/godot_cone_twist_joint_3d.cpp | 2 +- .../joints/godot_cone_twist_joint_3d.h | 7 +- .../joints/godot_generic_6dof_joint_3d.h | 5 +- .../joints/godot_hinge_joint_3d.h | 9 +- .../joints/godot_jacobian_entry_3d.h | 5 +- .../joints/godot_pin_joint_3d.h | 5 +- .../joints/godot_slider_joint_3d.h | 5 +- .../modules/godot_physics_3d/register_types.h | 5 +- .../gridmap/editor/grid_map_editor_plugin.cpp | 56 +- .../gridmap/editor/grid_map_editor_plugin.h | 12 +- engine/modules/gridmap/grid_map.cpp | 111 +- engine/modules/gridmap/grid_map.h | 23 +- engine/modules/gridmap/icons/GridMap.svg | 2 +- engine/modules/gridmap/register_types.cpp | 2 + engine/modules/gridmap/register_types.h | 5 +- engine/modules/hdr/image_loader_hdr.h | 5 +- engine/modules/hdr/register_types.h | 5 +- .../audio_stream_interactive.cpp | 18 +- .../audio_stream_interactive.h | 7 +- .../interactive_music/audio_stream_playlist.h | 6 +- .../audio_stream_synchronized.h | 7 +- ...audio_stream_interactive_editor_plugin.cpp | 9 +- .../audio_stream_interactive_editor_plugin.h | 5 +- .../interactive_music/register_types.h | 5 +- engine/modules/jolt_physics/SCsub | 7 +- engine/modules/jolt_physics/config.py | 2 +- .../joints/jolt_cone_twist_joint_3d.h | 5 +- .../joints/jolt_generic_6dof_joint_3d.h | 5 +- .../jolt_physics/joints/jolt_hinge_joint_3d.h | 5 +- .../jolt_physics/joints/jolt_joint_3d.cpp | 2 +- .../jolt_physics/joints/jolt_joint_3d.h | 5 +- .../jolt_physics/joints/jolt_pin_joint_3d.h | 5 +- .../joints/jolt_slider_joint_3d.h | 5 +- engine/modules/jolt_physics/jolt_globals.h | 5 +- .../jolt_physics/jolt_physics_server_3d.h | 5 +- .../jolt_physics/jolt_project_settings.cpp | 189 +- .../jolt_physics/jolt_project_settings.h | 95 +- .../jolt_physics/misc/jolt_math_funcs.cpp | 70 + .../jolt_physics/misc/jolt_math_funcs.h | 56 + .../jolt_physics/misc/jolt_stream_wrappers.h | 5 +- .../jolt_physics/misc/jolt_type_conversions.h | 5 +- .../jolt_physics/objects/jolt_area_3d.cpp | 8 +- .../jolt_physics/objects/jolt_area_3d.h | 5 +- .../jolt_physics/objects/jolt_body_3d.cpp | 16 +- .../jolt_physics/objects/jolt_body_3d.h | 5 +- .../jolt_physics/objects/jolt_group_filter.h | 5 +- .../jolt_physics/objects/jolt_object_3d.h | 5 +- .../jolt_physics_direct_body_state_3d.h | 5 +- .../objects/jolt_shaped_object_3d.cpp | 10 +- .../objects/jolt_shaped_object_3d.h | 5 +- .../objects/jolt_soft_body_3d.cpp | 4 +- .../jolt_physics/objects/jolt_soft_body_3d.h | 5 +- .../modules/jolt_physics/register_types.cpp | 32 +- engine/modules/jolt_physics/register_types.h | 5 +- .../jolt_physics/shapes/jolt_box_shape_3d.cpp | 2 +- .../jolt_physics/shapes/jolt_box_shape_3d.h | 5 +- .../shapes/jolt_capsule_shape_3d.h | 5 +- .../shapes/jolt_concave_polygon_shape_3d.cpp | 4 +- .../shapes/jolt_concave_polygon_shape_3d.h | 5 +- .../shapes/jolt_convex_polygon_shape_3d.cpp | 2 +- .../shapes/jolt_convex_polygon_shape_3d.h | 5 +- .../shapes/jolt_custom_decorated_shape.h | 5 +- .../shapes/jolt_custom_double_sided_shape.cpp | 15 +- .../shapes/jolt_custom_double_sided_shape.h | 7 +- .../shapes/jolt_custom_motion_shape.h | 5 +- .../shapes/jolt_custom_ray_shape.h | 5 +- .../shapes/jolt_custom_shape_type.h | 5 +- .../shapes/jolt_custom_user_data_shape.h | 5 +- .../shapes/jolt_cylinder_shape_3d.cpp | 2 +- .../shapes/jolt_cylinder_shape_3d.h | 5 +- .../shapes/jolt_height_map_shape_3d.cpp | 6 +- .../shapes/jolt_height_map_shape_3d.h | 5 +- .../shapes/jolt_separation_ray_shape_3d.h | 5 +- .../jolt_physics/shapes/jolt_shape_3d.h | 5 +- .../shapes/jolt_shape_instance_3d.h | 5 +- .../shapes/jolt_sphere_shape_3d.h | 5 +- .../shapes/jolt_world_boundary_shape_3d.cpp | 4 +- .../shapes/jolt_world_boundary_shape_3d.h | 5 +- .../spaces/jolt_body_accessor_3d.h | 5 +- .../spaces/jolt_broad_phase_layer.h | 5 +- .../spaces/jolt_contact_listener_3d.cpp | 2 +- .../spaces/jolt_contact_listener_3d.h | 6 +- .../jolt_physics/spaces/jolt_job_system.h | 6 +- .../jolt_physics/spaces/jolt_layers.cpp | 2 +- .../modules/jolt_physics/spaces/jolt_layers.h | 7 +- .../spaces/jolt_motion_filter_3d.h | 5 +- .../jolt_physics_direct_space_state_3d.cpp | 56 +- .../jolt_physics_direct_space_state_3d.h | 5 +- .../spaces/jolt_query_collectors.h | 5 +- .../spaces/jolt_query_filter_3d.h | 5 +- .../jolt_physics/spaces/jolt_space_3d.cpp | 46 +- .../jolt_physics/spaces/jolt_space_3d.h | 7 +- .../spaces/jolt_temp_allocator.cpp | 4 +- .../jolt_physics/spaces/jolt_temp_allocator.h | 5 +- engine/modules/jpg/SCsub | 2 +- engine/modules/jpg/image_loader_jpegd.h | 5 +- engine/modules/jpg/register_types.h | 5 +- engine/modules/jsonrpc/jsonrpc.compat.inc | 41 + engine/modules/jsonrpc/jsonrpc.cpp | 53 +- engine/modules/jsonrpc/jsonrpc.h | 14 +- engine/modules/jsonrpc/register_types.h | 5 +- engine/modules/jsonrpc/tests/test_jsonrpc.cpp | 10 +- engine/modules/jsonrpc/tests/test_jsonrpc.h | 82 +- engine/modules/ktx/SCsub | 12 +- engine/modules/ktx/register_types.cpp | 14 +- engine/modules/ktx/register_types.h | 5 +- engine/modules/ktx/texture_loader_ktx.h | 5 +- .../modules/lightmapper_rd/lightmapper_rd.cpp | 6 +- .../modules/lightmapper_rd/lightmapper_rd.h | 5 +- .../modules/lightmapper_rd/register_types.h | 5 +- engine/modules/mbedtls/SCsub | 2 +- engine/modules/mbedtls/crypto_mbedtls.cpp | 3 +- engine/modules/mbedtls/crypto_mbedtls.h | 57 +- engine/modules/mbedtls/dtls_server_mbedtls.h | 13 +- .../modules/mbedtls/packet_peer_mbed_dtls.h | 5 +- engine/modules/mbedtls/register_types.h | 5 +- engine/modules/mbedtls/stream_peer_mbedtls.h | 5 +- .../mbedtls/tests/test_crypto_mbedtls.h | 5 +- engine/modules/mbedtls/tls_context_mbedtls.h | 9 +- engine/modules/meshoptimizer/register_types.h | 5 +- engine/modules/minimp3/SCsub | 6 +- engine/modules/minimp3/audio_stream_mp3.h | 5 +- engine/modules/minimp3/register_types.cpp | 37 +- engine/modules/minimp3/register_types.h | 5 +- .../modules/minimp3/resource_importer_mp3.h | 5 +- engine/modules/mobile_vr/config.py | 2 +- .../modules/mobile_vr/mobile_vr_interface.cpp | 1 - .../modules/mobile_vr/mobile_vr_interface.h | 5 +- engine/modules/mobile_vr/register_types.h | 5 +- engine/modules/mono/class_db_api_json.h | 5 +- engine/modules/mono/csharp_script.cpp | 10 +- engine/modules/mono/csharp_script.h | 5 +- .../Godot.NET.Sdk/Godot.NET.Sdk.csproj | 2 +- .../Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props | 9 - .../Godot.NET.Sdk/Sdk/Sdk.targets | 13 + .../NestedInGenericTest.cs | 15 + .../ScriptPropertyDefValGeneratorTests.cs | 7 + ...perties2_ScriptPropertyDefVal.generated.cs | 25 + ... T).NestedClass_ScriptMethods.generated.cs | 16 + .../TestData/Sources/ExportedProperties2.cs | 13 + .../TestData/Sources/NestedInGeneric.cs | 9 + .../AnalyzerReleases.Shipped.md | 19 + .../AnalyzerReleases.Unshipped.md | 9 - .../ExtensionMethods.cs | 2 +- .../Godot.SourceGenerators.csproj | 2 +- .../ScriptPropertyDefValGenerator.cs | 106 +- .../GodotTools.ProjectEditor/ProjectUtils.cs | 7 + .../GodotTools/Export/ExportPlugin.cs | 56 +- .../GodotTools/GodotTools/ExternalEditorId.cs | 3 +- .../GodotTools/GodotTools/GodotSharpEditor.cs | 42 +- .../GodotTools/GodotTools/GodotTools.csproj | 2 +- .../GodotTools/Ides/GodotIdeManager.cs | 3 + .../GodotTools/Ides/Rider/RiderPathManager.cs | 85 +- .../editor/GodotTools/GodotTools/Utils/OS.cs | 2 +- .../mono/editor/bindings_generator.cpp | 95 +- .../modules/mono/editor/bindings_generator.h | 7 +- .../modules/mono/editor/code_completion.cpp | 2 +- engine/modules/mono/editor/code_completion.h | 5 +- .../mono/editor/editor_internal_calls.cpp | 14 +- .../mono/editor/editor_internal_calls.h | 5 +- .../modules/mono/editor/hostfxr_resolver.cpp | 24 +- engine/modules/mono/editor/hostfxr_resolver.h | 5 +- engine/modules/mono/editor/semver.h | 5 +- .../ExtensionMethods.cs | 2 +- .../glue/GodotSharp/GodotSharp/Core/Array.cs | 11 +- .../GodotSharp/GodotSharp/Core/Dictionary.cs | 11 +- .../Core/NativeInterop/InteropStructs.cs | 6 + .../Core/NativeInterop/NativeFuncs.cs | 6 + .../Core/NativeInterop/VariantUtils.cs | 9 +- .../GodotSharp/GodotSharp/Core/Projection.cs | 27 + .../GodotSharp/Core/SignalAwaiter.cs | 15 +- .../GodotSharp/Core/StringExtensions.cs | 76 +- .../GodotSharp/GodotSharp/Core/Vector3.cs | 61 + .../GodotSharp/GodotSharp/GodotSharp.csproj | 2 +- .../GodotSharpEditor/GodotSharpEditor.csproj | 2 +- engine/modules/mono/glue/runtime_interop.cpp | 12 +- engine/modules/mono/glue/runtime_interop.h | 5 +- engine/modules/mono/godotsharp_defs.h | 5 +- engine/modules/mono/godotsharp_dirs.cpp | 2 +- engine/modules/mono/godotsharp_dirs.h | 5 +- engine/modules/mono/icons/BuildCSharp.svg | 2 +- engine/modules/mono/icons/CSharpScript.svg | 2 +- engine/modules/mono/interop_types.h | 5 +- engine/modules/mono/managed_callable.h | 5 +- engine/modules/mono/mono_gc_handle.h | 5 +- engine/modules/mono/mono_gd/gd_mono.cpp | 24 +- engine/modules/mono/mono_gd/gd_mono.h | 9 +- engine/modules/mono/mono_gd/gd_mono_cache.h | 7 +- engine/modules/mono/register_types.cpp | 26 +- engine/modules/mono/register_types.h | 5 +- engine/modules/mono/signal_awaiter_utils.h | 5 +- engine/modules/mono/utils/macos_utils.cpp | 6 +- engine/modules/mono/utils/macos_utils.h | 5 +- engine/modules/mono/utils/macros.h | 5 +- engine/modules/mono/utils/naming_utils.h | 5 +- engine/modules/mono/utils/path_utils.cpp | 22 +- engine/modules/mono/utils/path_utils.h | 9 +- engine/modules/mono/utils/string_utils.cpp | 4 +- engine/modules/mono/utils/string_utils.h | 5 +- engine/modules/msdfgen/SCsub | 2 +- engine/modules/msdfgen/register_types.h | 5 +- .../editor/editor_network_profiler.cpp | 28 +- .../editor/editor_network_profiler.h | 5 +- .../editor/multiplayer_editor_plugin.h | 7 +- .../multiplayer/editor/replication_editor.cpp | 2 + .../multiplayer/editor/replication_editor.h | 6 +- .../multiplayer/multiplayer_debugger.cpp | 14 +- .../multiplayer/multiplayer_debugger.h | 5 +- .../multiplayer/multiplayer_spawner.cpp | 6 +- .../modules/multiplayer/multiplayer_spawner.h | 7 +- .../multiplayer/multiplayer_synchronizer.cpp | 4 +- .../multiplayer/multiplayer_synchronizer.h | 5 +- engine/modules/multiplayer/register_types.cpp | 10 +- engine/modules/multiplayer/register_types.h | 5 +- .../multiplayer/scene_cache_interface.cpp | 10 +- .../multiplayer/scene_cache_interface.h | 5 +- .../modules/multiplayer/scene_multiplayer.cpp | 11 +- .../modules/multiplayer/scene_multiplayer.h | 5 +- .../multiplayer/scene_replication_config.h | 5 +- .../scene_replication_interface.cpp | 5 +- .../multiplayer/scene_replication_interface.h | 7 +- .../multiplayer/scene_rpc_interface.cpp | 10 +- .../modules/multiplayer/scene_rpc_interface.h | 5 +- .../tests/test_multiplayer_spawner.h | 445 + .../tests/test_scene_multiplayer.h | 5 +- .../2d/godot_navigation_server_2d.cpp | 550 - .../2d/godot_navigation_server_2d.cpp | 1406 + .../2d/godot_navigation_server_2d.h | 202 +- .../navigation_2d/2d/nav_base_iteration_2d.h | 58 + .../navigation_2d/2d/nav_map_builder_2d.cpp | 404 + .../navigation_2d/2d/nav_map_builder_2d.h | 49 + .../navigation_2d/2d/nav_map_iteration_2d.h | 110 + .../2d/nav_mesh_generator_2d.cpp | 11 +- .../2d/nav_mesh_generator_2d.h | 5 +- .../navigation_2d/2d/nav_mesh_queries_2d.cpp | 1058 + .../navigation_2d/2d/nav_mesh_queries_2d.h | 141 + .../2d/nav_region_iteration_2d.h | 46 + engine/modules/navigation_2d/SCsub | 42 + engine/modules/navigation_2d/config.py | 6 + engine/modules/navigation_2d/nav_agent_2d.cpp | 315 + engine/modules/navigation_2d/nav_agent_2d.h | 148 + .../nav_base_2d.h} | 17 +- engine/modules/navigation_2d/nav_link_2d.cpp | 180 + engine/modules/navigation_2d/nav_link_2d.h | 99 + engine/modules/navigation_2d/nav_map_2d.cpp | 768 + engine/modules/navigation_2d/nav_map_2d.h | 248 + .../modules/navigation_2d/nav_obstacle_2d.cpp | 222 + .../modules/navigation_2d/nav_obstacle_2d.h | 100 + .../modules/navigation_2d/nav_region_2d.cpp | 318 + engine/modules/navigation_2d/nav_region_2d.h | 114 + .../nav_rid.h => navigation_2d/nav_rid_2d.h} | 9 +- engine/modules/navigation_2d/nav_utils_2d.h | 208 + .../modules/navigation_2d/register_types.cpp | 52 + .../register_types.h | 9 +- engine/modules/navigation_2d/triangle2.cpp | 112 + engine/modules/navigation_2d/triangle2.h | 52 + .../3d/godot_navigation_server_3d.cpp | 374 +- .../3d/godot_navigation_server_3d.h | 43 +- .../3d/nav_base_iteration_3d.h | 11 +- .../3d/nav_map_builder_3d.cpp | 176 +- .../3d/nav_map_builder_3d.h | 25 +- .../3d/nav_map_iteration_3d.h | 47 +- .../3d/nav_mesh_generator_3d.cpp | 11 +- .../3d/nav_mesh_generator_3d.h | 9 +- .../3d/nav_mesh_queries_3d.cpp | 366 +- .../3d/nav_mesh_queries_3d.h | 64 +- .../3d/nav_region_iteration_3d.h | 11 +- .../3d/navigation_mesh_generator.cpp | 4 - .../3d/navigation_mesh_generator.h | 11 +- .../{navigation => navigation_3d}/SCsub | 29 +- .../{navigation => navigation_3d}/config.py | 5 +- .../editor/navigation_mesh_editor_plugin.cpp | 12 +- .../editor/navigation_mesh_editor_plugin.h | 11 +- .../nav_agent_3d.cpp} | 70 +- .../nav_agent_3d.h} | 25 +- engine/modules/navigation_3d/nav_base_3d.h | 67 + .../nav_link_3d.cpp} | 38 +- .../nav_link_3d.h} | 30 +- .../nav_map_3d.cpp} | 244 +- .../nav_map.h => navigation_3d/nav_map_3d.h} | 120 +- .../nav_obstacle_3d.cpp} | 48 +- .../nav_obstacle_3d.h} | 33 +- .../nav_region_3d.cpp} | 55 +- .../nav_region_3d.h} | 35 +- engine/modules/navigation_3d/nav_rid_3d.h | 41 + .../nav_utils_3d.h} | 152 +- .../register_types.cpp | 19 +- engine/modules/navigation_3d/register_types.h | 36 + engine/modules/noise/SCsub | 6 +- .../noise/editor/noise_editor_plugin.cpp | 4 - .../noise/editor/noise_editor_plugin.h | 9 +- engine/modules/noise/fastnoise_lite.h | 5 +- engine/modules/noise/icons/NoiseTexture2D.svg | 2 +- engine/modules/noise/icons/NoiseTexture3D.svg | 2 +- engine/modules/noise/noise.cpp | 2 +- engine/modules/noise/noise.h | 5 +- engine/modules/noise/noise_texture_2d.h | 5 +- engine/modules/noise/noise_texture_3d.h | 5 +- engine/modules/noise/register_types.h | 5 +- .../modules/noise/tests/test_fastnoise_lite.h | 5 +- .../noise/tests/test_noise_texture_2d.h | 5 +- .../noise/tests/test_noise_texture_3d.h | 5 +- engine/modules/ogg/SCsub | 2 +- engine/modules/ogg/ogg_packet_sequence.h | 5 +- engine/modules/ogg/register_types.h | 5 +- engine/modules/openxr/SCsub | 4 +- .../modules/openxr/action_map/openxr_action.h | 5 +- .../openxr/action_map/openxr_action_map.h | 5 +- .../openxr/action_map/openxr_action_set.cpp | 2 +- .../openxr/action_map/openxr_action_set.h | 5 +- .../action_map/openxr_binding_modifier.h | 5 +- .../action_map/openxr_haptic_feedback.h | 5 +- .../action_map/openxr_interaction_profile.h | 5 +- .../openxr_interaction_profile_metadata.h | 5 +- engine/modules/openxr/config.py | 7 +- .../openxr/doc_classes/OpenXRAPIExtension.xml | 29 +- .../OpenXRAnalogThresholdModifier.xml | 4 +- .../doc_classes/OpenXRCompositionLayer.xml | 99 + .../doc_classes/OpenXRDpadBindingModifier.xml | 8 +- .../doc_classes/OpenXRExtensionWrapper.xml | 305 + .../OpenXRExtensionWrapperExtension.xml | 268 +- .../doc_classes/OpenXRFutureExtension.xml | 43 + .../openxr/doc_classes/OpenXRFutureResult.xml | 50 + .../openxr/doc_classes/OpenXRInterface.xml | 104 +- .../openxr/editor/openxr_action_editor.cpp | 14 +- .../openxr/editor/openxr_action_editor.h | 5 +- .../editor/openxr_action_map_editor.cpp | 6 +- .../openxr/editor/openxr_action_map_editor.h | 6 +- .../editor/openxr_action_set_editor.cpp | 16 +- .../openxr/editor/openxr_action_set_editor.h | 5 +- .../editor/openxr_binding_modifier_editor.cpp | 3 +- .../editor/openxr_binding_modifier_editor.h | 5 +- .../openxr_binding_modifiers_dialog.cpp | 4 +- .../editor/openxr_binding_modifiers_dialog.h | 5 +- .../openxr/editor/openxr_editor_plugin.cpp | 3 - .../openxr/editor/openxr_editor_plugin.h | 6 +- .../openxr_interaction_profile_editor.cpp | 3 + .../openxr_interaction_profile_editor.h | 5 +- .../editor/openxr_select_action_dialog.cpp | 4 +- .../editor/openxr_select_action_dialog.h | 5 +- ...enxr_select_interaction_profile_dialog.cpp | 4 +- ...openxr_select_interaction_profile_dialog.h | 5 +- .../openxr/editor/openxr_select_runtime.cpp | 7 +- .../openxr/editor/openxr_select_runtime.h | 5 +- ...openxr_composition_layer_depth_extension.h | 13 +- .../openxr_composition_layer_extension.cpp | 45 + .../openxr_composition_layer_extension.h | 68 +- .../extensions/openxr_debug_utils_extension.h | 10 +- .../openxr_dpad_binding_extension.h | 10 +- ...nsion.cpp => openxr_extension_wrapper.cpp} | 152 +- .../extensions/openxr_extension_wrapper.h | 146 +- .../openxr_extension_wrapper_extension.h | 118 +- .../openxr_eye_gaze_interaction.cpp | 10 +- .../extensions/openxr_eye_gaze_interaction.h | 10 +- ...openxr_fb_display_refresh_rate_extension.h | 10 +- .../openxr_fb_foveation_extension.h | 10 +- .../openxr_fb_update_swapchain_extension.cpp | 245 + .../openxr_fb_update_swapchain_extension.h | 26 +- .../extensions/openxr_future_extension.cpp | 254 + .../extensions/openxr_future_extension.h | 132 + .../openxr_hand_interaction_extension.cpp | 50 +- .../openxr_hand_interaction_extension.h | 10 +- .../openxr_hand_tracking_extension.cpp | 4 +- .../openxr_hand_tracking_extension.h | 10 +- .../openxr_htc_controller_extension.cpp | 110 +- .../openxr_htc_controller_extension.h | 10 +- .../openxr_htc_vive_tracker_extension.cpp | 58 +- .../openxr_htc_vive_tracker_extension.h | 10 +- .../openxr_huawei_controller_extension.cpp | 42 +- .../openxr_huawei_controller_extension.h | 10 +- .../extensions/openxr_local_floor_extension.h | 10 +- .../openxr_meta_controller_extension.cpp | 148 +- .../openxr_meta_controller_extension.h | 10 +- .../openxr_ml2_controller_extension.cpp | 40 +- .../openxr_ml2_controller_extension.h | 10 +- .../extensions/openxr_mxink_extension.cpp | 54 +- .../extensions/openxr_mxink_extension.h | 10 +- .../extensions/openxr_palm_pose_extension.h | 10 +- .../openxr_performance_settings_extension.cpp | 156 + .../openxr_performance_settings_extension.h} | 74 +- .../openxr_pico_controller_extension.cpp | 106 +- .../openxr_pico_controller_extension.h | 10 +- .../openxr_valve_analog_threshold_extension.h | 10 +- .../openxr_visibility_mask_extension.h | 10 +- .../openxr_wmr_controller_extension.cpp | 104 +- .../openxr_wmr_controller_extension.h | 10 +- .../platform/openxr_android_extension.h | 5 +- .../platform/openxr_metal_extension.h | 5 +- .../platform/openxr_metal_extension.mm | 5 +- .../platform/openxr_opengl_extension.cpp | 7 +- .../platform/openxr_opengl_extension.h | 5 +- .../platform/openxr_vulkan_extension.h | 5 +- engine/modules/openxr/openxr_api.cpp | 152 +- engine/modules/openxr/openxr_api.h | 22 +- .../openxr/openxr_api_extension.compat.inc | 58 + .../modules/openxr/openxr_api_extension.cpp | 30 +- engine/modules/openxr/openxr_api_extension.h | 26 +- engine/modules/openxr/openxr_interface.cpp | 49 +- engine/modules/openxr/openxr_interface.h | 33 +- engine/modules/openxr/openxr_platform_inc.h | 5 +- engine/modules/openxr/openxr_util.h | 5 +- engine/modules/openxr/register_types.cpp | 25 +- engine/modules/openxr/register_types.h | 5 +- .../openxr/scene/openxr_composition_layer.cpp | 224 +- .../openxr/scene/openxr_composition_layer.h | 80 +- .../openxr_composition_layer_cylinder.cpp | 4 +- .../scene/openxr_composition_layer_cylinder.h | 9 +- .../openxr_composition_layer_equirect.cpp | 10 +- .../scene/openxr_composition_layer_equirect.h | 17 +- .../scene/openxr_composition_layer_quad.h | 5 +- engine/modules/openxr/scene/openxr_hand.cpp | 2 +- engine/modules/openxr/scene/openxr_hand.h | 5 +- .../openxr/scene/openxr_visibility_mask.cpp | 2 +- .../openxr/scene/openxr_visibility_mask.h | 5 +- engine/modules/openxr/util.h | 5 +- engine/modules/raycast/SCsub | 2 +- .../raycast/lightmap_raycaster_embree.h | 5 +- .../raycast/raycast_occlusion_cull.cpp | 36 +- .../modules/raycast/raycast_occlusion_cull.h | 7 +- engine/modules/raycast/register_types.h | 5 +- .../modules/raycast/static_raycaster_embree.h | 5 +- engine/modules/regex/SCsub | 3 +- engine/modules/regex/icons/RegEx.svg | 2 +- engine/modules/regex/icons/RegExMatch.svg | 2 +- engine/modules/regex/regex.cpp | 8 +- engine/modules/regex/regex.h | 5 +- engine/modules/regex/register_types.h | 5 +- engine/modules/regex/tests/test_regex.h | 5 +- engine/modules/register_module_types.h | 5 +- engine/modules/svg/SCsub | 10 +- engine/modules/svg/image_loader_svg.cpp | 2 +- engine/modules/svg/image_loader_svg.h | 5 +- engine/modules/svg/register_types.h | 5 +- engine/modules/text_server_adv/SCsub | 79 +- .../gdextension_build/SConstruct | 2 +- .../modules/text_server_adv/register_types.h | 5 +- .../modules/text_server_adv/script_iterator.h | 5 +- .../text_server_adv/text_server_adv.cpp | 340 +- .../modules/text_server_adv/text_server_adv.h | 53 +- .../text_server_adv/thorvg_svg_in_ot.cpp | 4 +- .../text_server_adv/thorvg_svg_in_ot.h | 5 +- engine/modules/text_server_fb/SCsub | 10 +- .../modules/text_server_fb/register_types.h | 5 +- .../modules/text_server_fb/text_server_fb.cpp | 271 +- .../modules/text_server_fb/text_server_fb.h | 37 +- .../text_server_fb/thorvg_svg_in_ot.cpp | 4 +- .../modules/text_server_fb/thorvg_svg_in_ot.h | 5 +- engine/modules/tga/image_loader_tga.h | 5 +- engine/modules/tga/register_types.h | 5 +- engine/modules/theora/SCsub | 6 +- engine/modules/theora/register_types.h | 5 +- engine/modules/theora/video_stream_theora.h | 5 +- engine/modules/tinyexr/SCsub | 2 +- engine/modules/tinyexr/image_loader_tinyexr.h | 5 +- .../modules/tinyexr/image_saver_tinyexr.cpp | 2 +- engine/modules/tinyexr/image_saver_tinyexr.h | 5 +- engine/modules/tinyexr/register_types.h | 5 +- engine/modules/upnp/SCsub | 4 +- engine/modules/upnp/register_types.h | 5 +- engine/modules/upnp/upnp.h | 5 +- engine/modules/upnp/upnp_device.h | 5 +- engine/modules/upnp/upnp_device_miniupnp.h | 5 +- engine/modules/upnp/upnp_miniupnp.h | 5 +- engine/modules/vhacd/SCsub | 2 +- engine/modules/vhacd/config.py | 2 +- engine/modules/vhacd/register_types.h | 5 +- engine/modules/vorbis/SCsub | 4 +- .../modules/vorbis/audio_stream_ogg_vorbis.h | 5 +- engine/modules/vorbis/register_types.cpp | 34 +- engine/modules/vorbis/register_types.h | 5 +- .../vorbis/resource_importer_ogg_vorbis.cpp | 2 +- .../vorbis/resource_importer_ogg_vorbis.h | 5 +- engine/modules/webp/SCsub | 2 +- engine/modules/webp/image_loader_webp.h | 5 +- engine/modules/webp/register_types.h | 5 +- engine/modules/webp/resource_saver_webp.h | 5 +- engine/modules/webp/webp_common.h | 5 +- engine/modules/webrtc/register_types.h | 5 +- engine/modules/webrtc/webrtc_data_channel.h | 5 +- .../webrtc/webrtc_data_channel_extension.h | 5 +- .../modules/webrtc/webrtc_data_channel_js.cpp | 6 +- .../modules/webrtc/webrtc_data_channel_js.h | 5 +- .../webrtc/webrtc_multiplayer_peer.cpp | 2 +- .../modules/webrtc/webrtc_multiplayer_peer.h | 5 +- .../modules/webrtc/webrtc_peer_connection.h | 5 +- .../webrtc/webrtc_peer_connection_extension.h | 5 +- .../webrtc/webrtc_peer_connection_js.h | 5 +- engine/modules/websocket/SCsub | 2 +- .../editor_debugger_server_websocket.cpp | 4 - .../editor/editor_debugger_server_websocket.h | 9 +- engine/modules/websocket/emws_peer.cpp | 6 +- engine/modules/websocket/emws_peer.h | 6 +- engine/modules/websocket/packet_buffer.h | 5 +- engine/modules/websocket/register_types.h | 5 +- .../remote_debugger_peer_websocket.h | 5 +- .../websocket/websocket_multiplayer_peer.h | 6 +- engine/modules/websocket/websocket_peer.h | 6 +- engine/modules/websocket/wsl_peer.cpp | 10 +- engine/modules/websocket/wsl_peer.h | 6 +- engine/modules/webxr/config.py | 2 +- engine/modules/webxr/godot_webxr.h | 5 +- engine/modules/webxr/register_types.h | 5 +- engine/modules/webxr/webxr_interface.h | 5 +- engine/modules/webxr/webxr_interface_js.cpp | 2 +- engine/modules/webxr/webxr_interface_js.h | 5 +- engine/modules/xatlas_unwrap/SCsub | 2 +- engine/modules/xatlas_unwrap/register_types.h | 5 +- engine/modules/zip/register_types.h | 5 +- engine/modules/zip/zip_packer.h | 5 +- engine/modules/zip/zip_reader.h | 5 +- engine/platform/SCsub | 6 +- engine/platform/android/README.md | 2 +- engine/platform/android/SCsub | 13 +- .../android/android_input_handler.cpp | 10 +- .../platform/android/android_input_handler.h | 9 +- engine/platform/android/android_keys_utils.h | 5 +- engine/platform/android/api/api.h | 5 +- .../platform/android/api/java_class_wrapper.h | 5 +- engine/platform/android/api/jni_singleton.h | 5 +- engine/platform/android/audio_driver_opensl.h | 5 +- engine/platform/android/detect.py | 2 +- engine/platform/android/dialog_utils_jni.h | 5 +- .../platform/android/dir_access_jandroid.cpp | 2 +- engine/platform/android/dir_access_jandroid.h | 6 +- .../android/display_server_android.cpp | 12 +- .../platform/android/display_server_android.h | 15 +- .../EditorExportPlatformAndroid.xml | 2 +- engine/platform/android/export/export.h | 5 +- .../platform/android/export/export_plugin.cpp | 529 +- .../platform/android/export/export_plugin.h | 29 +- .../android/export/godot_plugin_config.h | 6 +- .../android/export/gradle_export_util.cpp | 31 +- .../android/export/gradle_export_util.h | 14 +- engine/platform/android/export/logo.svg | 2 +- engine/platform/android/export/run_icon.svg | 2 +- .../platform/android/file_access_android.cpp | 12 +- engine/platform/android/file_access_android.h | 8 +- .../file_access_filesystem_jandroid.cpp | 40 +- .../android/file_access_filesystem_jandroid.h | 10 +- .../platform/android/game_menu_utils_jni.cpp | 9 + engine/platform/android/game_menu_utils_jni.h | 6 +- .../android/java/app/AndroidManifest.xml | 11 +- engine/platform/android/java/app/build.gradle | 5 - .../platform/android/java/app/config.gradle | 19 - .../editor/src/horizonos/AndroidManifest.xml | 2 + .../java/editor/src/main/AndroidManifest.xml | 8 +- .../org/godotengine/editor/BaseGodotEditor.kt | 27 +- .../org/godotengine/editor/BaseGodotGame.kt | 4 + .../java/org/godotengine/editor/GodotGame.kt | 8 + .../editor/embed/GameMenuFragment.kt | 13 + .../src/main/res/drawable/audio_player.xml | 15 + .../drawable/audio_player_icon_selector.xml | 5 + .../main/res/drawable/audio_player_muted.xml | 16 + .../res/layout/game_menu_fragment_layout.xml | 9 + .../lib/src/org/godotengine/godot/Godot.kt | 5 +- .../src/org/godotengine/godot/GodotLib.java | 5 + .../godot/input/GodotEditText.java | 7 - .../godot/input/GodotGestureHandler.kt | 6 +- .../godot/input/GodotInputHandler.java | 52 +- .../godotengine/godot/io/file/AssetData.kt | 2 + .../godotengine/godot/io/file/DataAccess.kt | 18 + .../godot/io/file/FileAccessHandler.kt | 30 + .../org/godotengine/godot/io/file/FileData.kt | 30 + .../godot/io/file/MediaStoreData.kt | 14 + .../godotengine/godot/utils/GameMenuUtils.kt | 3 + .../platform/android/java_class_wrapper.cpp | 531 +- .../android/java_godot_io_wrapper.cpp | 1 - .../platform/android/java_godot_io_wrapper.h | 5 +- .../platform/android/java_godot_lib_jni.cpp | 19 +- engine/platform/android/java_godot_lib_jni.h | 6 +- .../android/java_godot_view_wrapper.h | 5 +- engine/platform/android/java_godot_wrapper.h | 5 +- engine/platform/android/jni_utils.h | 7 +- engine/platform/android/net_socket_android.h | 5 +- engine/platform/android/os_android.cpp | 31 +- engine/platform/android/os_android.h | 5 +- engine/platform/android/platform_config.h | 2 + engine/platform/android/platform_gl.h | 5 +- .../android/plugin/godot_plugin_jni.h | 5 +- .../rendering_context_driver_vulkan_android.h | 5 +- engine/platform/android/thread_jandroid.h | 5 +- engine/platform/android/tts_android.cpp | 97 +- engine/platform/android/tts_android.h | 7 +- .../platform/android/variant/callable_jni.h | 5 +- engine/platform/ios/SCsub | 8 +- engine/platform/ios/api/api.h | 5 +- engine/platform/ios/app_delegate.h | 2 + engine/platform/ios/detect.py | 2 +- engine/platform/ios/device_metrics.h | 2 + engine/platform/ios/display_layer.h | 2 + engine/platform/ios/display_server_ios.h | 11 +- engine/platform/ios/display_server_ios.mm | 47 +- .../doc_classes/EditorExportPlatformIOS.xml | 4 +- engine/platform/ios/export/export.h | 5 +- engine/platform/ios/export/export_plugin.cpp | 97 +- engine/platform/ios/export/export_plugin.h | 6 +- .../platform/ios/export/godot_plugin_config.h | 6 +- engine/platform/ios/export/logo.svg | 2 +- engine/platform/ios/export/run_icon.svg | 2 +- engine/platform/ios/godot_app_delegate.h | 2 + engine/platform/ios/godot_view.h | 2 + engine/platform/ios/godot_view.mm | 29 +- engine/platform/ios/godot_view_renderer.h | 2 + engine/platform/ios/ios.h | 5 +- engine/platform/ios/ios_terminal_logger.h | 5 +- engine/platform/ios/ios_terminal_logger.mm | 4 +- engine/platform/ios/key_mapping_ios.h | 5 +- engine/platform/ios/keyboard_input_view.h | 2 + engine/platform/ios/keyboard_input_view.mm | 3 +- engine/platform/ios/os_ios.h | 5 +- engine/platform/ios/os_ios.mm | 39 +- engine/platform/ios/platform_config.h | 4 + engine/platform/ios/platform_gl.h | 5 +- engine/platform/ios/platform_thread.h | 33 + .../ios/rendering_context_driver_vulkan_ios.h | 5 +- engine/platform/ios/tts_ios.h | 5 +- engine/platform/ios/view_controller.h | 2 + engine/platform/linuxbsd/README.md | 2 +- engine/platform/linuxbsd/SCsub | 1 + .../linuxbsd/crash_handler_linuxbsd.cpp | 9 +- .../linuxbsd/crash_handler_linuxbsd.h | 5 +- engine/platform/linuxbsd/detect.py | 26 +- engine/platform/linuxbsd/export/export.h | 5 +- .../linuxbsd/export/export_plugin.cpp | 13 +- .../platform/linuxbsd/export/export_plugin.h | 5 +- engine/platform/linuxbsd/export/logo.svg | 2 +- engine/platform/linuxbsd/export/run_icon.svg | 2 +- .../linuxbsd/freedesktop_at_spi_monitor.cpp | 157 + .../linuxbsd/freedesktop_at_spi_monitor.h} | 32 +- .../linuxbsd/freedesktop_portal_desktop.cpp | 376 +- .../linuxbsd/freedesktop_portal_desktop.h | 48 +- .../linuxbsd/freedesktop_screensaver.cpp | 4 +- .../linuxbsd/freedesktop_screensaver.h | 5 +- engine/platform/linuxbsd/joypad_linux.cpp | 2 +- engine/platform/linuxbsd/joypad_linux.h | 7 +- engine/platform/linuxbsd/msvs.py | 11 + engine/platform/linuxbsd/os_linuxbsd.cpp | 91 +- engine/platform/linuxbsd/os_linuxbsd.h | 8 +- engine/platform/linuxbsd/platform_config.h | 2 + engine/platform/linuxbsd/platform_gl.h | 5 +- engine/platform/linuxbsd/tts_linux.cpp | 2 +- engine/platform/linuxbsd/tts_linux.h | 5 +- .../linuxbsd/wayland/detect_prime_egl.h | 7 +- .../wayland/display_server_wayland.cpp | 799 +- .../linuxbsd/wayland/display_server_wayland.h | 63 +- .../linuxbsd/wayland/egl_manager_wayland.h | 5 +- .../wayland/egl_manager_wayland_gles.h | 5 +- .../linuxbsd/wayland/key_mapping_xkb.h | 5 +- .../rendering_context_driver_vulkan_wayland.h | 5 +- .../linuxbsd/wayland/wayland_thread.cpp | 956 +- .../linuxbsd/wayland/wayland_thread.h | 84 +- .../linuxbsd/x11/detect_prime_x11.cpp | 48 +- .../platform/linuxbsd/x11/detect_prime_x11.h | 30 +- .../linuxbsd/x11/display_server_x11.cpp | 275 +- .../linuxbsd/x11/display_server_x11.h | 27 +- engine/platform/linuxbsd/x11/gl_manager_x11.h | 5 +- .../linuxbsd/x11/gl_manager_x11_egl.h | 6 +- .../platform/linuxbsd/x11/key_mapping_x11.h | 5 +- .../x11/rendering_context_driver_vulkan_x11.h | 5 +- engine/platform/macos/SCsub | 4 +- engine/platform/macos/crash_handler_macos.h | 5 +- engine/platform/macos/crash_handler_macos.mm | 12 +- engine/platform/macos/detect.py | 16 +- engine/platform/macos/dir_access_macos.h | 7 +- engine/platform/macos/dir_access_macos.mm | 10 +- engine/platform/macos/display_server_macos.h | 30 +- engine/platform/macos/display_server_macos.mm | 719 +- engine/platform/macos/export/export.h | 5 +- .../platform/macos/export/export_plugin.cpp | 46 +- engine/platform/macos/export/export_plugin.h | 6 +- engine/platform/macos/export/logo.svg | 2 +- engine/platform/macos/export/run_icon.svg | 2 +- .../platform/macos/gl_manager_macos_angle.h | 12 +- .../platform/macos/gl_manager_macos_angle.mm | 4 +- .../platform/macos/gl_manager_macos_legacy.h | 11 +- .../platform/macos/gl_manager_macos_legacy.mm | 7 +- engine/platform/macos/godot_application.h | 5 +- engine/platform/macos/godot_application.mm | 8 +- .../macos/godot_application_delegate.h | 20 +- .../macos/godot_application_delegate.mm | 133 +- engine/platform/macos/godot_button_view.h | 5 +- engine/platform/macos/godot_button_view.mm | 2 +- engine/platform/macos/godot_content_view.h | 10 +- engine/platform/macos/godot_content_view.mm | 14 +- engine/platform/macos/godot_main_macos.mm | 30 +- engine/platform/macos/godot_menu_delegate.h | 5 +- engine/platform/macos/godot_menu_delegate.mm | 10 +- engine/platform/macos/godot_menu_item.h | 6 +- engine/platform/macos/godot_menu_item.mm | 3 +- .../platform/macos/godot_open_save_delegate.h | 5 +- .../macos/godot_open_save_delegate.mm | 6 +- engine/platform/macos/godot_status_item.h | 5 +- engine/platform/macos/godot_status_item.mm | 4 +- engine/platform/macos/godot_window.h | 5 +- engine/platform/macos/godot_window.mm | 4 +- engine/platform/macos/godot_window_delegate.h | 5 +- .../platform/macos/godot_window_delegate.mm | 24 +- engine/platform/macos/key_mapping_macos.h | 5 +- engine/platform/macos/key_mapping_macos.mm | 4 +- engine/platform/macos/macos_terminal_logger.h | 5 +- .../platform/macos/macos_terminal_logger.mm | 2 +- engine/platform/macos/msvs.py | 11 + engine/platform/macos/native_menu_macos.h | 5 +- engine/platform/macos/native_menu_macos.mm | 41 +- engine/platform/macos/os_macos.h | 26 +- engine/platform/macos/os_macos.mm | 217 +- engine/platform/macos/platform_config.h | 4 + engine/platform/macos/platform_gl.h | 5 +- engine/platform/macos/platform_thread.h | 33 + .../rendering_context_driver_vulkan_macos.h | 5 +- .../rendering_context_driver_vulkan_macos.mm | 2 +- engine/platform/macos/tts_macos.h | 5 +- engine/platform/macos/tts_macos.mm | 2 +- engine/platform/register_platform_apis.h | 5 +- engine/platform/web/README.md | 2 +- engine/platform/web/SCsub | 12 +- engine/platform/web/api/api.h | 5 +- .../web/api/javascript_bridge_singleton.h | 5 +- engine/platform/web/audio_driver_web.cpp | 2 +- engine/platform/web/audio_driver_web.h | 5 +- engine/platform/web/detect.py | 17 +- engine/platform/web/display_server_web.cpp | 10 +- engine/platform/web/display_server_web.h | 8 +- .../web/editor/web_tools_editor_plugin.h | 12 +- engine/platform/web/emscripten_helpers.py | 14 +- .../platform/web/export/editor_http_server.h | 5 +- engine/platform/web/export/export.h | 5 +- engine/platform/web/export/export_plugin.cpp | 42 +- engine/platform/web/export/export_plugin.h | 15 +- engine/platform/web/export/logo.svg | 2 +- engine/platform/web/export/run_icon.svg | 2 +- engine/platform/web/godot_audio.h | 5 +- engine/platform/web/godot_js.h | 5 +- engine/platform/web/godot_midi.h | 5 +- engine/platform/web/godot_webgl2.h | 5 +- engine/platform/web/http_client_web.cpp | 4 +- engine/platform/web/http_client_web.h | 5 +- engine/platform/web/ip_web.h | 5 +- .../web/javascript_bridge_singleton.cpp | 2 + engine/platform/web/net_socket_web.h | 5 +- engine/platform/web/os_web.cpp | 2 +- engine/platform/web/os_web.h | 5 +- engine/platform/web/platform_config.h | 2 + engine/platform/web/platform_gl.h | 5 +- engine/platform/web/webmidi_driver.h | 5 +- engine/platform/windows/SCsub | 15 +- .../platform/windows/crash_handler_windows.h | 5 +- .../windows/crash_handler_windows_seh.cpp | 6 +- .../windows/crash_handler_windows_signal.cpp | 8 +- engine/platform/windows/detect.py | 278 +- .../windows/display_server_windows.cpp | 486 +- .../platform/windows/display_server_windows.h | 27 +- engine/platform/windows/drop_target_windows.h | 15 +- engine/platform/windows/export/export.h | 5 +- .../platform/windows/export/export_plugin.cpp | 68 +- .../platform/windows/export/export_plugin.h | 5 +- engine/platform/windows/export/logo.svg | 2 +- engine/platform/windows/export/run_icon.svg | 2 +- .../windows/gl_manager_windows_angle.h | 6 +- .../windows/gl_manager_windows_native.cpp | 2 +- .../windows/gl_manager_windows_native.h | 6 +- engine/platform/windows/godot_res.rc | 12 +- engine/platform/windows/godot_res_wrap.rc | 12 +- engine/platform/windows/joypad_windows.cpp | 2 +- engine/platform/windows/joypad_windows.h | 5 +- engine/platform/windows/key_mapping_windows.h | 5 +- engine/platform/windows/lang_table.h | 5 +- engine/platform/windows/msvs.py | 8 +- engine/platform/windows/native_menu_windows.h | 5 +- engine/platform/windows/os_windows.cpp | 283 +- engine/platform/windows/os_windows.h | 15 +- engine/platform/windows/platform_config.h | 2 + engine/platform/windows/platform_gl.h | 5 +- .../rendering_context_driver_vulkan_windows.h | 5 +- engine/platform/windows/tts_windows.h | 5 +- .../windows/uiautomationcore.arm32.def | 115 + .../windows/uiautomationcore.arm64.def | 115 + .../windows/uiautomationcore.x86_32.def | 115 + .../windows/uiautomationcore.x86_64.def | 115 + engine/platform/windows/wgl_detect_version.h | 5 +- .../windows/windows_terminal_logger.h | 5 +- engine/platform/windows/windows_utils.cpp | 9 +- engine/platform/windows/windows_utils.h | 5 +- engine/scene/2d/SCsub | 5 +- engine/scene/2d/animated_sprite_2d.cpp | 13 +- engine/scene/2d/animated_sprite_2d.h | 5 +- engine/scene/2d/audio_listener_2d.h | 5 +- engine/scene/2d/audio_stream_player_2d.cpp | 9 +- engine/scene/2d/audio_stream_player_2d.h | 5 +- engine/scene/2d/back_buffer_copy.h | 5 +- engine/scene/2d/camera_2d.cpp | 210 +- engine/scene/2d/camera_2d.h | 47 +- engine/scene/2d/canvas_group.cpp | 32 + engine/scene/2d/canvas_group.h | 7 +- engine/scene/2d/canvas_modulate.h | 5 +- engine/scene/2d/cpu_particles_2d.cpp | 86 +- engine/scene/2d/cpu_particles_2d.h | 15 +- engine/scene/2d/gpu_particles_2d.cpp | 83 +- engine/scene/2d/gpu_particles_2d.h | 12 +- engine/scene/2d/light_2d.h | 5 +- engine/scene/2d/light_occluder_2d.cpp | 6 +- engine/scene/2d/light_occluder_2d.h | 5 +- engine/scene/2d/line_2d.cpp | 8 +- engine/scene/2d/line_2d.h | 5 +- engine/scene/2d/line_builder.cpp | 10 +- engine/scene/2d/line_builder.h | 5 +- engine/scene/2d/marker_2d.h | 5 +- engine/scene/2d/mesh_instance_2d.cpp | 5 +- engine/scene/2d/mesh_instance_2d.h | 7 +- engine/scene/2d/multimesh_instance_2d.cpp | 5 +- engine/scene/2d/multimesh_instance_2d.h | 7 +- engine/scene/2d/navigation/SCsub | 6 + .../{ => navigation}/navigation_agent_2d.cpp | 17 +- .../2d/{ => navigation}/navigation_agent_2d.h | 5 +- .../{ => navigation}/navigation_link_2d.cpp | 8 +- .../2d/{ => navigation}/navigation_link_2d.h | 5 +- .../navigation_obstacle_2d.cpp | 2 +- .../{ => navigation}/navigation_obstacle_2d.h | 5 +- .../{ => navigation}/navigation_region_2d.cpp | 50 +- .../{ => navigation}/navigation_region_2d.h | 7 +- engine/scene/2d/node_2d.cpp | 7 + engine/scene/2d/node_2d.h | 5 +- engine/scene/2d/parallax_2d.h | 5 +- engine/scene/2d/parallax_background.h | 5 +- engine/scene/2d/parallax_layer.h | 5 +- engine/scene/2d/path_2d.cpp | 9 +- engine/scene/2d/path_2d.h | 5 +- engine/scene/2d/physics/animatable_body_2d.h | 5 +- engine/scene/2d/physics/area_2d.h | 5 +- engine/scene/2d/physics/character_body_2d.cpp | 4 +- engine/scene/2d/physics/character_body_2d.h | 5 +- .../scene/2d/physics/collision_object_2d.cpp | 2 +- engine/scene/2d/physics/collision_object_2d.h | 5 +- .../scene/2d/physics/collision_polygon_2d.cpp | 4 +- .../scene/2d/physics/collision_polygon_2d.h | 5 +- .../scene/2d/physics/collision_shape_2d.cpp | 4 +- engine/scene/2d/physics/collision_shape_2d.h | 5 +- .../physics/joints/damped_spring_joint_2d.h | 5 +- .../scene/2d/physics/joints/groove_joint_2d.h | 5 +- engine/scene/2d/physics/joints/joint_2d.h | 5 +- engine/scene/2d/physics/joints/pin_joint_2d.h | 5 +- .../2d/physics/kinematic_collision_2d.cpp | 2 +- .../scene/2d/physics/kinematic_collision_2d.h | 5 +- engine/scene/2d/physics/physical_bone_2d.h | 5 +- engine/scene/2d/physics/physics_body_2d.h | 5 +- engine/scene/2d/physics/ray_cast_2d.h | 5 +- engine/scene/2d/physics/rigid_body_2d.cpp | 3 +- engine/scene/2d/physics/rigid_body_2d.h | 5 +- engine/scene/2d/physics/shape_cast_2d.h | 5 +- engine/scene/2d/physics/static_body_2d.cpp | 8 +- engine/scene/2d/physics/static_body_2d.h | 7 +- .../2d/{ => physics}/touch_screen_button.cpp | 19 + .../2d/{ => physics}/touch_screen_button.h | 7 +- engine/scene/2d/polygon_2d.cpp | 10 +- engine/scene/2d/polygon_2d.h | 9 +- engine/scene/2d/remote_transform_2d.cpp | 4 +- engine/scene/2d/remote_transform_2d.h | 5 +- engine/scene/2d/skeleton_2d.cpp | 2 +- engine/scene/2d/skeleton_2d.h | 5 +- engine/scene/2d/sprite_2d.cpp | 11 + engine/scene/2d/sprite_2d.h | 5 +- engine/scene/2d/tile_map.compat.inc | 4 + engine/scene/2d/tile_map.cpp | 24 + engine/scene/2d/tile_map.h | 23 +- engine/scene/2d/tile_map_layer.cpp | 854 +- engine/scene/2d/tile_map_layer.h | 142 +- .../2d/visible_on_screen_notifier_2d.cpp | 39 +- .../scene/2d/visible_on_screen_notifier_2d.h | 19 +- engine/scene/3d/SCsub | 7 +- engine/scene/3d/audio_listener_3d.h | 5 +- engine/scene/3d/audio_stream_player_3d.cpp | 53 +- engine/scene/3d/audio_stream_player_3d.h | 12 +- engine/scene/3d/bone_attachment_3d.cpp | 8 +- engine/scene/3d/bone_attachment_3d.h | 5 +- engine/scene/3d/camera_3d.cpp | 6 + engine/scene/3d/camera_3d.h | 9 +- engine/scene/3d/cpu_particles_3d.cpp | 12 +- engine/scene/3d/cpu_particles_3d.h | 5 +- engine/scene/3d/decal.cpp | 2 +- engine/scene/3d/decal.h | 5 +- engine/scene/3d/fog_volume.h | 5 +- engine/scene/3d/gpu_particles_3d.cpp | 4 +- engine/scene/3d/gpu_particles_3d.h | 5 +- engine/scene/3d/gpu_particles_collision_3d.h | 5 +- engine/scene/3d/importer_mesh_instance_3d.h | 5 +- engine/scene/3d/label_3d.cpp | 18 +- engine/scene/3d/label_3d.h | 9 +- engine/scene/3d/light_3d.cpp | 6 +- engine/scene/3d/light_3d.h | 5 +- engine/scene/3d/lightmap_gi.cpp | 17 +- engine/scene/3d/lightmap_gi.h | 5 +- engine/scene/3d/lightmap_probe.h | 5 +- engine/scene/3d/lightmapper.h | 19 +- engine/scene/3d/look_at_modifier_3d.cpp | 20 +- engine/scene/3d/look_at_modifier_3d.h | 19 +- engine/scene/3d/marker_3d.h | 5 +- engine/scene/3d/mesh_instance_3d.cpp | 17 +- engine/scene/3d/mesh_instance_3d.h | 13 +- engine/scene/3d/multimesh_instance_3d.cpp | 4 + engine/scene/3d/multimesh_instance_3d.h | 11 +- engine/scene/3d/navigation/SCsub | 6 + .../{ => navigation}/navigation_agent_3d.cpp | 21 +- .../3d/{ => navigation}/navigation_agent_3d.h | 5 +- .../{ => navigation}/navigation_link_3d.cpp | 6 + .../3d/{ => navigation}/navigation_link_3d.h | 5 +- .../navigation_obstacle_3d.cpp | 10 +- .../{ => navigation}/navigation_obstacle_3d.h | 5 +- .../{ => navigation}/navigation_region_3d.cpp | 63 +- .../{ => navigation}/navigation_region_3d.h | 7 +- engine/scene/3d/node_3d.cpp | 7 + engine/scene/3d/node_3d.h | 5 +- engine/scene/3d/occluder_instance_3d.cpp | 10 +- engine/scene/3d/occluder_instance_3d.h | 5 +- engine/scene/3d/path_3d.cpp | 49 +- engine/scene/3d/path_3d.h | 16 +- engine/scene/3d/physics/animatable_body_3d.h | 5 +- engine/scene/3d/physics/area_3d.h | 5 +- engine/scene/3d/physics/character_body_3d.cpp | 6 +- engine/scene/3d/physics/character_body_3d.h | 5 +- .../scene/3d/physics/collision_object_3d.cpp | 2 +- engine/scene/3d/physics/collision_object_3d.h | 5 +- .../scene/3d/physics/collision_polygon_3d.cpp | 4 +- .../scene/3d/physics/collision_polygon_3d.h | 5 +- engine/scene/3d/physics/collision_shape_3d.h | 5 +- .../3d/physics/joints/cone_twist_joint_3d.cpp | 4 +- .../3d/physics/joints/cone_twist_joint_3d.h | 5 +- .../3d/physics/joints/generic_6dof_joint_3d.h | 5 +- .../3d/physics/joints/hinge_joint_3d.cpp | 4 +- .../scene/3d/physics/joints/hinge_joint_3d.h | 5 +- engine/scene/3d/physics/joints/joint_3d.h | 5 +- engine/scene/3d/physics/joints/pin_joint_3d.h | 5 +- .../scene/3d/physics/joints/slider_joint_3d.h | 5 +- .../3d/physics/kinematic_collision_3d.cpp | 2 +- .../scene/3d/physics/kinematic_collision_3d.h | 5 +- engine/scene/3d/physics/physical_bone_3d.cpp | 12 +- engine/scene/3d/physics/physical_bone_3d.h | 13 +- .../physical_bone_simulator_3d.cpp | 13 +- .../physical_bone_simulator_3d.h | 7 +- engine/scene/3d/physics/physics_body_3d.h | 5 +- engine/scene/3d/physics/ray_cast_3d.cpp | 2 +- engine/scene/3d/physics/ray_cast_3d.h | 5 +- engine/scene/3d/physics/rigid_body_3d.cpp | 3 +- engine/scene/3d/physics/rigid_body_3d.h | 5 +- engine/scene/3d/physics/shape_cast_3d.h | 5 +- .../3d/{ => physics}/soft_body_3d.compat.inc | 0 .../scene/3d/{ => physics}/soft_body_3d.cpp | 0 engine/scene/3d/{ => physics}/soft_body_3d.h | 5 +- engine/scene/3d/physics/spring_arm_3d.h | 5 +- engine/scene/3d/physics/static_body_3d.cpp | 4 + engine/scene/3d/physics/static_body_3d.h | 9 +- engine/scene/3d/physics/vehicle_body_3d.cpp | 12 +- engine/scene/3d/physics/vehicle_body_3d.h | 5 +- engine/scene/3d/reflection_probe.cpp | 4 +- engine/scene/3d/reflection_probe.h | 5 +- engine/scene/3d/remote_transform_3d.cpp | 72 +- engine/scene/3d/remote_transform_3d.h | 5 +- engine/scene/3d/retarget_modifier_3d.cpp | 12 +- engine/scene/3d/retarget_modifier_3d.h | 7 +- engine/scene/3d/skeleton_3d.cpp | 71 +- engine/scene/3d/skeleton_3d.h | 15 +- engine/scene/3d/skeleton_ik_3d.cpp | 4 +- engine/scene/3d/skeleton_ik_3d.h | 7 +- engine/scene/3d/skeleton_modifier_3d.cpp | 20 +- engine/scene/3d/skeleton_modifier_3d.h | 13 +- engine/scene/3d/spring_bone_collision_3d.h | 5 +- .../3d/spring_bone_collision_capsule_3d.h | 5 +- .../scene/3d/spring_bone_collision_plane_3d.h | 5 +- .../3d/spring_bone_collision_sphere_3d.h | 5 +- engine/scene/3d/spring_bone_simulator_3d.cpp | 52 +- engine/scene/3d/spring_bone_simulator_3d.h | 13 +- engine/scene/3d/sprite_3d.cpp | 2 +- engine/scene/3d/sprite_3d.h | 5 +- engine/scene/3d/velocity_tracker_3d.h | 5 +- .../3d/visible_on_screen_notifier_3d.cpp | 2 +- .../scene/3d/visible_on_screen_notifier_3d.h | 5 +- engine/scene/3d/visual_instance_3d.h | 5 +- engine/scene/3d/voxel_gi.cpp | 2 + engine/scene/3d/voxel_gi.h | 5 +- engine/scene/3d/voxelizer.cpp | 20 +- engine/scene/3d/voxelizer.h | 5 +- engine/scene/3d/world_environment.h | 5 +- engine/scene/3d/xr/SCsub | 6 + .../scene/3d/{ => xr}/xr_body_modifier_3d.cpp | 2 +- .../scene/3d/{ => xr}/xr_body_modifier_3d.h | 7 +- .../scene/3d/{ => xr}/xr_face_modifier_3d.cpp | 2 +- .../scene/3d/{ => xr}/xr_face_modifier_3d.h | 7 +- .../scene/3d/{ => xr}/xr_hand_modifier_3d.cpp | 2 +- .../scene/3d/{ => xr}/xr_hand_modifier_3d.h | 7 +- engine/scene/3d/{ => xr}/xr_nodes.cpp | 86 +- engine/scene/3d/{ => xr}/xr_nodes.h | 10 +- .../animation/animation_blend_space_1d.cpp | 6 + .../animation/animation_blend_space_1d.h | 5 +- .../animation/animation_blend_space_2d.cpp | 28 +- .../animation/animation_blend_space_2d.h | 5 +- .../scene/animation/animation_blend_tree.cpp | 2 +- engine/scene/animation/animation_blend_tree.h | 5 +- engine/scene/animation/animation_mixer.cpp | 42 +- engine/scene/animation/animation_mixer.h | 5 +- .../animation/animation_node_extension.h | 5 +- .../animation_node_state_machine.cpp | 2 +- .../animation/animation_node_state_machine.h | 5 +- engine/scene/animation/animation_player.cpp | 3 +- engine/scene/animation/animation_player.h | 5 +- engine/scene/animation/animation_tree.cpp | 8 +- engine/scene/animation/animation_tree.h | 5 +- engine/scene/animation/easing_equations.h | 69 +- engine/scene/animation/root_motion_view.h | 5 +- engine/scene/animation/tween.cpp | 62 +- engine/scene/animation/tween.h | 7 +- engine/scene/audio/audio_stream_player.cpp | 9 +- engine/scene/audio/audio_stream_player.h | 5 +- .../audio/audio_stream_player_internal.h | 5 +- engine/scene/debugger/scene_debugger.cpp | 1139 +- engine/scene/debugger/scene_debugger.h | 125 +- engine/scene/gui/aspect_ratio_container.h | 5 +- engine/scene/gui/base_button.cpp | 72 +- engine/scene/gui/base_button.h | 6 +- engine/scene/gui/box_container.h | 5 +- engine/scene/gui/button.cpp | 66 +- engine/scene/gui/button.h | 10 +- engine/scene/gui/center_container.h | 5 +- engine/scene/gui/check_box.cpp | 20 +- engine/scene/gui/check_box.h | 10 +- engine/scene/gui/check_button.cpp | 14 +- engine/scene/gui/check_button.h | 8 +- engine/scene/gui/code_edit.cpp | 49 +- engine/scene/gui/code_edit.h | 5 +- engine/scene/gui/color_mode.h | 9 +- engine/scene/gui/color_picker.cpp | 742 +- engine/scene/gui/color_picker.h | 51 +- engine/scene/gui/color_picker_shape.cpp | 771 + engine/scene/gui/color_picker_shape.h | 215 + engine/scene/gui/color_rect.cpp | 8 + engine/scene/gui/color_rect.h | 5 +- engine/scene/gui/container.cpp | 7 + engine/scene/gui/container.h | 5 +- engine/scene/gui/control.cpp | 592 +- engine/scene/gui/control.h | 55 +- engine/scene/gui/dialogs.compat.inc | 2 + engine/scene/gui/dialogs.cpp | 45 +- engine/scene/gui/dialogs.h | 11 +- engine/scene/gui/file_dialog.cpp | 103 +- engine/scene/gui/file_dialog.h | 5 +- engine/scene/gui/flow_container.h | 5 +- engine/scene/gui/foldable_container.cpp | 652 + engine/scene/gui/foldable_container.h | 171 + engine/scene/gui/graph_edit.cpp | 275 +- engine/scene/gui/graph_edit.h | 21 +- engine/scene/gui/graph_edit_arranger.h | 5 +- engine/scene/gui/graph_element.h | 5 +- engine/scene/gui/graph_frame.h | 5 +- engine/scene/gui/graph_node.cpp | 387 +- engine/scene/gui/graph_node.h | 21 +- engine/scene/gui/grid_container.h | 5 +- engine/scene/gui/item_list.cpp | 218 +- engine/scene/gui/item_list.h | 21 +- engine/scene/gui/label.cpp | 106 +- engine/scene/gui/label.h | 11 +- engine/scene/gui/line_edit.cpp | 271 +- engine/scene/gui/line_edit.h | 19 +- engine/scene/gui/link_button.cpp | 20 +- engine/scene/gui/link_button.h | 5 +- engine/scene/gui/margin_container.h | 5 +- engine/scene/gui/menu_bar.cpp | 26 +- engine/scene/gui/menu_bar.h | 5 +- engine/scene/gui/menu_button.cpp | 10 +- engine/scene/gui/menu_button.h | 5 +- engine/scene/gui/nine_patch_rect.h | 5 +- engine/scene/gui/option_button.cpp | 50 +- engine/scene/gui/option_button.h | 8 +- engine/scene/gui/panel.cpp | 7 + engine/scene/gui/panel.h | 5 +- engine/scene/gui/panel_container.h | 5 +- engine/scene/gui/popup.cpp | 16 +- engine/scene/gui/popup.h | 7 +- engine/scene/gui/popup_menu.cpp | 308 +- engine/scene/gui/popup_menu.h | 20 +- engine/scene/gui/progress_bar.cpp | 8 + engine/scene/gui/progress_bar.h | 5 +- engine/scene/gui/range.cpp | 52 +- engine/scene/gui/range.h | 10 +- engine/scene/gui/reference_rect.h | 5 +- engine/scene/gui/rich_text_effect.h | 5 +- engine/scene/gui/rich_text_label.compat.inc | 12 +- engine/scene/gui/rich_text_label.cpp | 860 +- engine/scene/gui/rich_text_label.h | 81 +- engine/scene/gui/scroll_bar.cpp | 9 + engine/scene/gui/scroll_bar.h | 5 +- engine/scene/gui/scroll_container.cpp | 80 + engine/scene/gui/scroll_container.h | 18 +- engine/scene/gui/separator.h | 5 +- engine/scene/gui/slider.cpp | 10 +- engine/scene/gui/slider.h | 5 +- engine/scene/gui/spin_box.cpp | 86 +- engine/scene/gui/spin_box.h | 23 +- engine/scene/gui/split_container.cpp | 55 + engine/scene/gui/split_container.h | 11 +- engine/scene/gui/subviewport_container.h | 5 +- engine/scene/gui/tab_bar.cpp | 225 +- engine/scene/gui/tab_bar.h | 20 +- engine/scene/gui/tab_container.cpp | 54 +- engine/scene/gui/tab_container.h | 10 +- engine/scene/gui/text_edit.cpp | 535 +- engine/scene/gui/text_edit.h | 49 +- engine/scene/gui/texture_button.h | 5 +- engine/scene/gui/texture_progress_bar.cpp | 9 +- engine/scene/gui/texture_progress_bar.h | 5 +- engine/scene/gui/texture_rect.h | 5 +- engine/scene/gui/tree.compat.inc | 41 + engine/scene/gui/tree.cpp | 926 +- engine/scene/gui/tree.h | 124 +- engine/scene/gui/video_stream_player.cpp | 37 +- engine/scene/gui/video_stream_player.h | 7 +- engine/scene/gui/view_panner.cpp | 4 +- engine/scene/gui/view_panner.h | 5 +- engine/scene/main/canvas_item.cpp | 46 +- engine/scene/main/canvas_item.h | 7 +- engine/scene/main/canvas_layer.h | 5 +- engine/scene/main/http_request.cpp | 2 +- engine/scene/main/http_request.h | 5 +- engine/scene/main/instance_placeholder.h | 5 +- engine/scene/main/missing_node.h | 5 +- engine/scene/main/multiplayer_api.h | 5 +- engine/scene/main/multiplayer_peer.cpp | 2 +- engine/scene/main/multiplayer_peer.h | 5 +- engine/scene/main/node.cpp | 338 +- engine/scene/main/node.h | 63 +- engine/scene/main/resource_preloader.cpp | 4 +- engine/scene/main/resource_preloader.h | 5 +- engine/scene/main/scene_tree.cpp | 211 +- engine/scene/main/scene_tree.h | 21 +- engine/scene/main/shader_globals_override.cpp | 2 +- engine/scene/main/shader_globals_override.h | 5 +- engine/scene/main/status_indicator.h | 5 +- engine/scene/main/timer.h | 5 +- engine/scene/main/viewport.cpp | 255 +- engine/scene/main/viewport.h | 34 +- engine/scene/main/window.cpp | 201 +- engine/scene/main/window.h | 32 +- engine/scene/property_list_helper.h | 5 +- engine/scene/property_utils.h | 5 +- engine/scene/register_scene_types.cpp | 408 +- engine/scene/register_scene_types.h | 5 +- engine/scene/resources/2d/SCsub | 20 +- .../scene/resources/2d/capsule_shape_2d.cpp | 2 +- engine/scene/resources/2d/capsule_shape_2d.h | 5 +- engine/scene/resources/2d/circle_shape_2d.cpp | 2 +- engine/scene/resources/2d/circle_shape_2d.h | 5 +- .../resources/2d/concave_polygon_shape_2d.cpp | 2 +- .../resources/2d/concave_polygon_shape_2d.h | 5 +- .../resources/2d/convex_polygon_shape_2d.h | 5 +- .../navigation_mesh_source_geometry_data_2d.h | 5 +- .../scene/resources/2d/navigation_polygon.cpp | 4 +- .../scene/resources/2d/navigation_polygon.h | 5 +- .../resources/2d/polygon_path_finder.cpp | 29 +- .../scene/resources/2d/polygon_path_finder.h | 5 +- .../scene/resources/2d/rectangle_shape_2d.h | 5 +- .../scene/resources/2d/segment_shape_2d.cpp | 3 +- engine/scene/resources/2d/segment_shape_2d.h | 5 +- .../resources/2d/separation_ray_shape_2d.cpp | 2 +- .../resources/2d/separation_ray_shape_2d.h | 5 +- engine/scene/resources/2d/shape_2d.h | 5 +- engine/scene/resources/2d/skeleton/SCsub | 16 + .../2d/skeleton/skeleton_modification_2d.cpp | 14 +- .../2d/skeleton/skeleton_modification_2d.h | 5 +- .../skeleton_modification_2d_ccdik.cpp | 4 +- .../skeleton/skeleton_modification_2d_ccdik.h | 7 +- .../skeleton_modification_2d_fabrik.cpp | 16 +- .../skeleton_modification_2d_fabrik.h | 5 +- .../skeleton_modification_2d_jiggle.cpp | 2 +- .../skeleton_modification_2d_jiggle.h | 5 +- .../skeleton_modification_2d_lookat.cpp | 4 +- .../skeleton_modification_2d_lookat.h | 7 +- ...skeleton_modification_2d_physicalbones.cpp | 6 +- .../skeleton_modification_2d_physicalbones.h | 5 +- .../skeleton_modification_2d_stackholder.h | 5 +- .../skeleton_modification_2d_twoboneik.cpp | 10 +- .../skeleton_modification_2d_twoboneik.h | 5 +- .../skeleton/skeleton_modification_stack_2d.h | 5 +- engine/scene/resources/2d/tile_set.compat.inc | 4 + engine/scene/resources/2d/tile_set.cpp | 229 +- engine/scene/resources/2d/tile_set.h | 54 +- .../resources/2d/world_boundary_shape_2d.cpp | 27 +- .../resources/2d/world_boundary_shape_2d.h | 5 +- engine/scene/resources/3d/SCsub | 23 +- engine/scene/resources/3d/box_shape_3d.h | 5 +- engine/scene/resources/3d/capsule_shape_3d.h | 5 +- .../resources/3d/concave_polygon_shape_3d.h | 5 +- .../resources/3d/convex_polygon_shape_3d.h | 5 +- engine/scene/resources/3d/cylinder_shape_3d.h | 5 +- engine/scene/resources/3d/fog_material.cpp | 2 +- engine/scene/resources/3d/fog_material.h | 5 +- .../scene/resources/3d/height_map_shape_3d.h | 5 +- engine/scene/resources/3d/importer_mesh.cpp | 28 +- engine/scene/resources/3d/importer_mesh.h | 14 +- engine/scene/resources/3d/mesh_library.cpp | 16 + engine/scene/resources/3d/mesh_library.h | 18 +- .../navigation_mesh_source_geometry_data_3d.h | 5 +- .../scene/resources/3d/primitive_meshes.cpp | 105 +- engine/scene/resources/3d/primitive_meshes.h | 9 +- .../resources/3d/separation_ray_shape_3d.h | 5 +- engine/scene/resources/3d/shape_3d.h | 5 +- engine/scene/resources/3d/skin.h | 5 +- engine/scene/resources/3d/sky_material.cpp | 6 +- engine/scene/resources/3d/sky_material.h | 5 +- engine/scene/resources/3d/sphere_shape_3d.h | 5 +- engine/scene/resources/3d/world_3d.cpp | 12 + engine/scene/resources/3d/world_3d.h | 10 +- .../resources/3d/world_boundary_shape_3d.h | 5 +- engine/scene/resources/animated_texture.h | 5 +- engine/scene/resources/animation.cpp | 44 +- engine/scene/resources/animation.h | 10 +- engine/scene/resources/animation_library.cpp | 12 +- engine/scene/resources/animation_library.h | 5 +- engine/scene/resources/atlas_texture.h | 5 +- .../scene/resources/audio_stream_polyphonic.h | 5 +- engine/scene/resources/audio_stream_wav.cpp | 199 +- engine/scene/resources/audio_stream_wav.h | 31 +- engine/scene/resources/bit_map.cpp | 1 - engine/scene/resources/bit_map.h | 5 +- engine/scene/resources/bone_map.h | 5 +- engine/scene/resources/camera_attributes.h | 5 +- engine/scene/resources/camera_texture.cpp | 1 + engine/scene/resources/camera_texture.h | 5 +- .../scene/resources/canvas_item_material.cpp | 2 +- engine/scene/resources/canvas_item_material.h | 5 +- engine/scene/resources/color_palette.h | 5 +- engine/scene/resources/compositor.h | 5 +- engine/scene/resources/compressed_texture.h | 5 +- engine/scene/resources/curve.cpp | 87 +- engine/scene/resources/curve.h | 36 +- engine/scene/resources/curve_texture.h | 5 +- engine/scene/resources/environment.h | 5 +- engine/scene/resources/external_texture.h | 5 +- engine/scene/resources/font.cpp | 52 +- engine/scene/resources/font.h | 13 +- engine/scene/resources/gradient.h | 5 +- engine/scene/resources/gradient_texture.cpp | 5 +- engine/scene/resources/gradient_texture.h | 5 +- engine/scene/resources/image_texture.h | 5 +- engine/scene/resources/immediate_mesh.h | 5 +- engine/scene/resources/label_settings.h | 5 +- engine/scene/resources/material.cpp | 38 +- engine/scene/resources/material.h | 5 +- engine/scene/resources/mesh.cpp | 32 +- engine/scene/resources/mesh.h | 18 +- engine/scene/resources/mesh_data_tool.h | 5 +- engine/scene/resources/mesh_texture.h | 5 +- engine/scene/resources/multimesh.h | 5 +- engine/scene/resources/navigation_mesh.cpp | 4 +- engine/scene/resources/navigation_mesh.h | 5 +- engine/scene/resources/packed_scene.cpp | 69 +- engine/scene/resources/packed_scene.h | 7 +- .../resources/particle_process_material.cpp | 17 +- .../resources/particle_process_material.h | 5 +- engine/scene/resources/physics_material.cpp | 2 + engine/scene/resources/physics_material.h | 7 +- engine/scene/resources/placeholder_textures.h | 5 +- .../resources/portable_compressed_texture.cpp | 71 +- .../resources/portable_compressed_texture.h | 6 +- .../scene/resources/resource_format_text.cpp | 27 +- engine/scene/resources/resource_format_text.h | 5 +- engine/scene/resources/shader.cpp | 6 +- engine/scene/resources/shader.h | 5 +- engine/scene/resources/shader_include.cpp | 2 +- engine/scene/resources/shader_include.h | 5 +- engine/scene/resources/skeleton_profile.h | 5 +- engine/scene/resources/sky.h | 5 +- engine/scene/resources/sprite_frames.h | 5 +- engine/scene/resources/style_box.h | 5 +- engine/scene/resources/style_box_flat.cpp | 108 +- engine/scene/resources/style_box_flat.h | 5 +- engine/scene/resources/style_box_line.h | 5 +- engine/scene/resources/style_box_texture.h | 5 +- engine/scene/resources/surface_tool.cpp | 10 +- engine/scene/resources/surface_tool.h | 5 +- engine/scene/resources/syntax_highlighter.cpp | 13 +- engine/scene/resources/syntax_highlighter.h | 5 +- engine/scene/resources/text_file.cpp | 2 +- engine/scene/resources/text_file.h | 5 +- engine/scene/resources/text_line.cpp | 18 +- engine/scene/resources/text_line.h | 6 +- engine/scene/resources/text_paragraph.cpp | 29 +- engine/scene/resources/text_paragraph.h | 8 +- engine/scene/resources/texture.h | 5 +- engine/scene/resources/texture_rd.h | 5 +- engine/scene/resources/theme.cpp | 2 +- engine/scene/resources/theme.h | 5 +- engine/scene/resources/video_stream.h | 5 +- engine/scene/resources/visual_shader.cpp | 5 +- engine/scene/resources/visual_shader.h | 8 +- engine/scene/resources/visual_shader_nodes.h | 5 +- .../visual_shader_particle_nodes.cpp | 12 +- .../resources/visual_shader_particle_nodes.h | 5 +- .../scene/resources/visual_shader_sdf_nodes.h | 5 +- engine/scene/resources/world_2d.cpp | 66 +- engine/scene/resources/world_2d.h | 20 +- engine/scene/scene_string_names.h | 5 +- engine/scene/theme/SCsub | 1 - engine/scene/theme/default_theme.cpp | 59 + engine/scene/theme/default_theme.h | 5 +- engine/scene/theme/default_theme_builders.py | 35 +- engine/scene/theme/icons/add.svg | 2 +- engine/scene/theme/icons/arrow_down.svg | 2 +- engine/scene/theme/icons/arrow_left.svg | 2 +- engine/scene/theme/icons/arrow_right.svg | 2 +- engine/scene/theme/icons/arrow_up.svg | 1 + engine/scene/theme/icons/bookmark.svg | 2 +- engine/scene/theme/icons/breakpoint.svg | 2 +- engine/scene/theme/icons/checked.svg | 2 +- engine/scene/theme/icons/checked_disabled.svg | 2 +- engine/scene/theme/icons/clear.svg | 2 +- engine/scene/theme/icons/close.svg | 2 +- engine/scene/theme/icons/close_hl.svg | 2 +- .../theme/icons/color_picker_bar_arrow.svg | 2 +- .../scene/theme/icons/color_picker_cursor.svg | 2 +- .../theme/icons/color_picker_cursor_bg.svg | 2 +- .../theme/icons/color_picker_overbright.svg | 2 +- .../theme/icons/color_picker_pipette.svg | 2 +- .../icons/default_theme_icons_builders.py | 58 +- engine/scene/theme/icons/error_icon.svg | 2 +- engine/scene/theme/icons/file.svg | 2 +- engine/scene/theme/icons/folder.svg | 2 +- engine/scene/theme/icons/folder_create.svg | 2 +- engine/scene/theme/icons/folder_up.svg | 2 +- engine/scene/theme/icons/graph_port.svg | 2 +- engine/scene/theme/icons/grid_layout.svg | 2 +- engine/scene/theme/icons/grid_minimap.svg | 2 +- engine/scene/theme/icons/grid_snap.svg | 2 +- engine/scene/theme/icons/grid_toggle.svg | 2 +- engine/scene/theme/icons/hslider_tick.svg | 2 +- engine/scene/theme/icons/hsplitter.svg | 2 +- engine/scene/theme/icons/indeterminate.svg | 2 +- .../theme/icons/indeterminate_disabled.svg | 2 +- engine/scene/theme/icons/line_edit_clear.svg | 2 +- engine/scene/theme/icons/load.svg | 2 +- .../scene/theme/icons/mini_checkerboard.svg | 2 +- .../scene/theme/icons/option_button_arrow.svg | 2 +- .../scene/theme/icons/picker_shape_circle.svg | 2 +- .../theme/icons/picker_shape_rectangle.svg | 2 +- .../icons/picker_shape_rectangle_wheel.svg | 2 +- .../theme/icons/popup_menu_arrow_left.svg | 2 +- .../theme/icons/popup_menu_arrow_right.svg | 2 +- engine/scene/theme/icons/radio_checked.svg | 2 +- .../theme/icons/radio_checked_disabled.svg | 2 +- engine/scene/theme/icons/radio_unchecked.svg | 2 +- .../theme/icons/radio_unchecked_disabled.svg | 2 +- engine/scene/theme/icons/region_folded.svg | 2 +- engine/scene/theme/icons/region_unfolded.svg | 2 +- engine/scene/theme/icons/reload.svg | 2 +- engine/scene/theme/icons/resizer_nw.svg | 2 +- engine/scene/theme/icons/resizer_se.svg | 2 +- engine/scene/theme/icons/save.svg | 2 +- .../scene/theme/icons/scroll_button_left.svg | 2 +- .../theme/icons/scroll_button_left_hl.svg | 2 +- .../scene/theme/icons/scroll_button_right.svg | 2 +- .../theme/icons/scroll_button_right_hl.svg | 2 +- engine/scene/theme/icons/slider_grabber.svg | 2 +- .../theme/icons/slider_grabber_disabled.svg | 2 +- .../scene/theme/icons/slider_grabber_hl.svg | 2 +- engine/scene/theme/icons/tabs_drop_mark.svg | 2 +- engine/scene/theme/icons/tabs_menu.svg | 2 +- engine/scene/theme/icons/tabs_menu_hl.svg | 2 +- .../scene/theme/icons/text_edit_ellipsis.svg | 2 +- engine/scene/theme/icons/text_edit_space.svg | 2 +- engine/scene/theme/icons/text_edit_tab.svg | 2 +- .../theme/icons/toggle_filename_filter.svg | 2 +- engine/scene/theme/icons/toggle_off.svg | 2 +- .../scene/theme/icons/toggle_off_disabled.svg | 2 +- .../icons/toggle_off_disabled_mirrored.svg | 2 +- .../scene/theme/icons/toggle_off_mirrored.svg | 2 +- engine/scene/theme/icons/toggle_on.svg | 2 +- .../scene/theme/icons/toggle_on_disabled.svg | 2 +- .../icons/toggle_on_disabled_mirrored.svg | 2 +- .../scene/theme/icons/toggle_on_mirrored.svg | 2 +- engine/scene/theme/icons/unchecked.svg | 2 +- .../scene/theme/icons/unchecked_disabled.svg | 2 +- engine/scene/theme/icons/updown.svg | 2 +- engine/scene/theme/icons/value_down.svg | 2 +- engine/scene/theme/icons/value_up.svg | 2 +- .../scene/theme/icons/visibility_visible.svg | 2 +- engine/scene/theme/icons/vslider_tick.svg | 2 +- engine/scene/theme/icons/vsplitter.svg | 2 +- engine/scene/theme/icons/zoom_less.svg | 2 +- engine/scene/theme/icons/zoom_more.svg | 2 +- engine/scene/theme/icons/zoom_reset.svg | 2 +- engine/scene/theme/theme_db.cpp | 2 +- engine/scene/theme/theme_db.h | 5 +- engine/scene/theme/theme_owner.h | 5 +- engine/scu_builders.py | 8 +- engine/servers/SCsub | 12 +- engine/servers/audio/audio_driver_dummy.h | 5 +- engine/servers/audio/audio_effect.h | 5 +- engine/servers/audio/audio_filter_sw.cpp | 6 +- engine/servers/audio/audio_filter_sw.h | 5 +- engine/servers/audio/audio_rb_resampler.h | 5 +- engine/servers/audio/audio_stream.h | 5 +- .../audio/effects/audio_effect_amplify.h | 5 +- .../audio/effects/audio_effect_capture.h | 5 +- .../audio/effects/audio_effect_chorus.cpp | 6 +- .../audio/effects/audio_effect_chorus.h | 5 +- .../audio/effects/audio_effect_compressor.h | 5 +- .../audio/effects/audio_effect_delay.cpp | 2 +- .../audio/effects/audio_effect_delay.h | 5 +- .../audio/effects/audio_effect_distortion.cpp | 4 +- .../audio/effects/audio_effect_distortion.h | 5 +- .../servers/audio/effects/audio_effect_eq.h | 5 +- .../audio/effects/audio_effect_filter.h | 5 +- .../effects/audio_effect_hard_limiter.cpp | 2 +- .../audio/effects/audio_effect_hard_limiter.h | 5 +- .../audio/effects/audio_effect_limiter.h | 5 +- .../audio/effects/audio_effect_panner.h | 5 +- .../audio/effects/audio_effect_phaser.cpp | 6 +- .../audio/effects/audio_effect_phaser.h | 5 +- .../effects/audio_effect_pitch_shift.cpp | 19 +- .../audio/effects/audio_effect_pitch_shift.h | 5 +- .../audio/effects/audio_effect_record.h | 5 +- .../audio/effects/audio_effect_reverb.h | 5 +- .../audio_effect_spectrum_analyzer.cpp | 4 +- .../effects/audio_effect_spectrum_analyzer.h | 5 +- .../effects/audio_effect_stereo_enhance.h | 5 +- .../audio/effects/audio_stream_generator.h | 5 +- engine/servers/audio/effects/eq_filter.cpp | 6 +- engine/servers/audio/effects/eq_filter.h | 5 +- .../servers/audio/effects/reverb_filter.cpp | 4 +- engine/servers/audio/effects/reverb_filter.h | 5 +- engine/servers/audio_server.cpp | 45 +- engine/servers/audio_server.h | 14 +- engine/servers/camera/camera_feed.h | 5 +- engine/servers/camera_server.cpp | 16 + engine/servers/camera_server.h | 9 +- engine/servers/debugger/servers_debugger.cpp | 26 +- engine/servers/debugger/servers_debugger.h | 5 +- engine/servers/display/native_menu.h | 5 +- engine/servers/display_server.compat.inc | 46 + engine/servers/display_server.cpp | 669 +- engine/servers/display_server.h | 332 +- engine/servers/display_server_headless.h | 11 +- .../extensions/physics_server_2d_extension.h | 5 +- .../extensions/physics_server_3d_extension.h | 5 +- engine/servers/movie_writer/movie_writer.cpp | 46 +- engine/servers/movie_writer/movie_writer.h | 5 +- .../servers/movie_writer/movie_writer_mjpeg.h | 5 +- .../movie_writer/movie_writer_pngwav.h | 5 +- engine/servers/navigation/SCsub | 8 +- engine/servers/navigation/nav_heap.h | 158 + .../servers/navigation/navigation_globals.h | 6 +- .../navigation_path_query_parameters_2d.cpp | 40 + .../navigation_path_query_parameters_2d.h | 13 +- .../navigation_path_query_parameters_3d.cpp | 40 + .../navigation_path_query_parameters_3d.h | 13 +- .../navigation_path_query_result_2d.cpp | 41 + .../navigation_path_query_result_2d.h | 7 +- .../navigation_path_query_result_3d.h | 5 +- .../servers/navigation/navigation_utilities.h | 5 +- engine/servers/navigation_server_2d.cpp | 208 +- engine/servers/navigation_server_2d.h | 80 +- engine/servers/navigation_server_2d_dummy.h | 10 +- engine/servers/navigation_server_3d.cpp | 123 +- engine/servers/navigation_server_3d.h | 8 +- engine/servers/navigation_server_3d_dummy.h | 8 +- engine/servers/physics_server_2d.h | 7 +- engine/servers/physics_server_2d_dummy.h | 5 +- engine/servers/physics_server_2d_wrap_mt.h | 5 +- engine/servers/physics_server_3d.h | 7 +- engine/servers/physics_server_3d_dummy.h | 5 +- engine/servers/physics_server_3d_wrap_mt.h | 5 +- engine/servers/register_server_types.cpp | 71 +- engine/servers/register_server_types.h | 5 +- .../servers/rendering/dummy/environment/fog.h | 5 +- .../servers/rendering/dummy/environment/gi.h | 5 +- .../rendering/dummy/rasterizer_canvas_dummy.h | 5 +- .../rendering/dummy/rasterizer_dummy.h | 6 +- .../rendering/dummy/rasterizer_scene_dummy.h | 5 +- .../rendering/dummy/storage/light_storage.h | 5 +- .../dummy/storage/material_storage.cpp | 2 +- .../dummy/storage/material_storage.h | 5 +- .../rendering/dummy/storage/mesh_storage.h | 5 +- .../dummy/storage/particles_storage.h | 5 +- .../rendering/dummy/storage/texture_storage.h | 5 +- .../rendering/dummy/storage/utilities.h | 5 +- .../rendering/environment/renderer_fog.h | 5 +- .../rendering/environment/renderer_gi.h | 5 +- engine/servers/rendering/instance_uniforms.h | 5 +- .../rendering/renderer_canvas_cull.cpp | 6 +- .../servers/rendering/renderer_canvas_cull.h | 5 +- .../rendering/renderer_canvas_render.h | 5 +- .../servers/rendering/renderer_compositor.cpp | 7 +- .../servers/rendering/renderer_compositor.h | 6 +- .../rendering/renderer_geometry_instance.h | 5 +- .../renderer_rd/cluster_builder_rd.h | 5 +- .../rendering/renderer_rd/effects/SCsub | 2 +- .../rendering/renderer_rd/effects/bokeh_dof.h | 5 +- .../renderer_rd/effects/copy_effects.h | 5 +- .../renderer_rd/effects/debug_effects.h | 5 +- .../rendering/renderer_rd/effects/fsr.h | 5 +- .../rendering/renderer_rd/effects/fsr2.h | 5 +- .../renderer_rd/effects/luminance.cpp | 8 +- .../rendering/renderer_rd/effects/luminance.h | 5 +- .../rendering/renderer_rd/effects/metal_fx.h | 5 +- .../rendering/renderer_rd/effects/metal_fx.mm | 20 +- .../effects/motion_vectors_store.h | 5 +- .../rendering/renderer_rd/effects/resolve.h | 5 +- .../renderer_rd/effects/roughness_limiter.h | 5 +- .../renderer_rd/effects/sort_effects.h | 6 +- .../renderer_rd/effects/spatial_upscaler.h | 5 +- .../renderer_rd/effects/ss_effects.cpp | 6 +- .../renderer_rd/effects/ss_effects.h | 5 +- .../rendering/renderer_rd/effects/taa.h | 5 +- .../renderer_rd/effects/tone_mapper.h | 5 +- .../rendering/renderer_rd/effects/vrs.cpp | 38 +- .../rendering/renderer_rd/effects/vrs.h | 7 +- .../rendering/renderer_rd/environment/fog.cpp | 9 +- .../rendering/renderer_rd/environment/fog.h | 5 +- .../rendering/renderer_rd/environment/gi.cpp | 32 +- .../rendering/renderer_rd/environment/gi.h | 5 +- .../rendering/renderer_rd/environment/sky.cpp | 22 +- .../rendering/renderer_rd/environment/sky.h | 5 +- .../render_forward_clustered.cpp | 98 +- .../render_forward_clustered.h | 89 +- .../scene_shader_forward_clustered.cpp | 6 +- .../scene_shader_forward_clustered.h | 5 +- .../forward_mobile/render_forward_mobile.cpp | 123 +- .../forward_mobile/render_forward_mobile.h | 94 +- .../scene_shader_forward_mobile.cpp | 6 +- .../scene_shader_forward_mobile.h | 5 +- .../renderer_rd/framebuffer_cache_rd.h | 14 +- .../rendering/renderer_rd/pipeline_cache_rd.h | 5 +- .../renderer_rd/pipeline_hash_map_rd.h | 45 +- .../renderer_rd/renderer_canvas_render_rd.cpp | 32 +- .../renderer_rd/renderer_canvas_render_rd.h | 7 +- .../renderer_rd/renderer_compositor_rd.cpp | 7 +- .../renderer_rd/renderer_compositor_rd.h | 6 +- .../renderer_rd/renderer_scene_render_rd.cpp | 60 +- .../renderer_rd/renderer_scene_render_rd.h | 7 +- .../rendering/renderer_rd/shader_rd.cpp | 20 +- .../servers/rendering/renderer_rd/shader_rd.h | 5 +- .../rendering/renderer_rd/shaders/canvas.glsl | 22 +- .../renderer_rd/shaders/effects/ssao.glsl | 6 +- .../renderer_rd/shaders/effects/ssil.glsl | 6 +- .../renderer_rd/shaders/effects/vrs.glsl | 9 + .../storage_rd/forward_id_storage.h | 5 +- .../renderer_rd/storage_rd/light_storage.cpp | 14 +- .../renderer_rd/storage_rd/light_storage.h | 5 +- .../storage_rd/material_storage.cpp | 4 +- .../renderer_rd/storage_rd/material_storage.h | 5 +- .../renderer_rd/storage_rd/mesh_storage.h | 5 +- .../storage_rd/particles_storage.cpp | 44 +- .../storage_rd/particles_storage.h | 5 +- .../storage_rd/render_buffer_custom_data_rd.h | 5 +- .../renderer_rd/storage_rd/render_data_rd.h | 5 +- .../storage_rd/render_scene_buffers_rd.cpp | 37 +- .../storage_rd/render_scene_buffers_rd.h | 5 +- .../storage_rd/render_scene_data_rd.h | 5 +- .../storage_rd/texture_storage.cpp | 119 +- .../renderer_rd/storage_rd/texture_storage.h | 5 +- .../renderer_rd/storage_rd/utilities.cpp | 4 + .../renderer_rd/storage_rd/utilities.h | 5 +- .../renderer_rd/uniform_set_cache_rd.h | 5 +- .../servers/rendering/renderer_scene_cull.cpp | 8 +- .../servers/rendering/renderer_scene_cull.h | 9 +- .../rendering/renderer_scene_occlusion_cull.h | 12 +- .../servers/rendering/renderer_scene_render.h | 5 +- .../servers/rendering/renderer_viewport.cpp | 84 +- engine/servers/rendering/renderer_viewport.h | 12 +- .../rendering/rendering_context_driver.h | 5 +- engine/servers/rendering/rendering_device.cpp | 904 +- engine/servers/rendering/rendering_device.h | 93 +- .../rendering/rendering_device_binds.cpp | 2 +- .../rendering/rendering_device_binds.h | 13 +- .../rendering/rendering_device_commons.cpp | 65 +- .../rendering/rendering_device_commons.h | 34 +- .../rendering/rendering_device_driver.h | 75 +- .../rendering/rendering_device_graph.cpp | 32 +- .../rendering/rendering_device_graph.h | 31 +- .../rendering/rendering_light_culler.h | 5 +- engine/servers/rendering/rendering_method.h | 11 +- .../rendering/rendering_server_constants.h | 5 +- .../rendering/rendering_server_default.cpp | 4 +- .../rendering/rendering_server_default.h | 5 +- .../rendering/rendering_server_globals.h | 5 +- engine/servers/rendering/shader_compiler.cpp | 4 +- engine/servers/rendering/shader_compiler.h | 5 +- engine/servers/rendering/shader_include_db.h | 5 +- engine/servers/rendering/shader_language.cpp | 83 +- engine/servers/rendering/shader_language.h | 5 +- .../servers/rendering/shader_preprocessor.cpp | 10 +- .../servers/rendering/shader_preprocessor.h | 5 +- engine/servers/rendering/shader_types.h | 5 +- engine/servers/rendering/shader_warnings.cpp | 2 +- engine/servers/rendering/shader_warnings.h | 5 +- .../storage/camera_attributes_storage.h | 5 +- .../rendering/storage/compositor_storage.h | 7 +- .../rendering/storage/environment_storage.h | 5 +- .../servers/rendering/storage/light_storage.h | 5 +- .../rendering/storage/material_storage.h | 5 +- .../servers/rendering/storage/mesh_storage.h | 5 +- .../rendering/storage/particles_storage.h | 5 +- .../servers/rendering/storage/render_data.h | 5 +- .../rendering/storage/render_scene_buffers.h | 5 +- .../rendering/storage/render_scene_data.h | 5 +- .../rendering/storage/texture_storage.h | 5 +- engine/servers/rendering/storage/utilities.h | 5 +- .../rendering/storage/variant_converters.h | 5 +- engine/servers/rendering_server.cpp | 20 +- engine/servers/rendering_server.h | 5 +- engine/servers/server_wrap_mt_common.h | 5 +- engine/servers/text/text_server_dummy.h | 5 +- engine/servers/text/text_server_extension.cpp | 91 + engine/servers/text/text_server_extension.h | 34 +- engine/servers/text_server.cpp | 110 +- engine/servers/text_server.h | 30 +- engine/servers/xr/xr_body_tracker.h | 7 +- engine/servers/xr/xr_controller_tracker.h | 5 +- engine/servers/xr/xr_face_tracker.h | 5 +- engine/servers/xr/xr_hand_tracker.h | 5 +- engine/servers/xr/xr_interface.cpp | 4 +- engine/servers/xr/xr_interface.h | 6 +- engine/servers/xr/xr_interface_extension.h | 5 +- engine/servers/xr/xr_pose.h | 5 +- engine/servers/xr/xr_positional_tracker.h | 5 +- engine/servers/xr/xr_tracker.h | 5 +- engine/servers/xr/xr_vrs.cpp | 19 +- engine/servers/xr/xr_vrs.h | 5 +- engine/servers/xr_server.cpp | 4 +- engine/servers/xr_server.h | 5 +- .../tests/core/config/test_project_settings.h | 7 +- engine/tests/core/input/test_input_event.h | 9 +- .../tests/core/input/test_input_event_key.h | 5 +- .../tests/core/input/test_input_event_mouse.h | 5 +- engine/tests/core/input/test_shortcut.h | 33 +- engine/tests/core/io/test_config_file.h | 5 +- engine/tests/core/io/test_file_access.h | 27 +- engine/tests/core/io/test_http_client.h | 10 +- engine/tests/core/io/test_image.h | 5 +- engine/tests/core/io/test_ip.h | 5 +- engine/tests/core/io/test_json.h | 21 +- engine/tests/core/io/test_json_native.h | 27 +- engine/tests/core/io/test_logger.h | 5 +- engine/tests/core/io/test_marshalls.h | 5 +- engine/tests/core/io/test_packet_peer.h | 5 +- engine/tests/core/io/test_pck_packer.h | 5 +- engine/tests/core/io/test_resource.h | 5 +- engine/tests/core/io/test_resource_uid.h | 5 +- engine/tests/core/io/test_stream_peer.h | 5 +- .../tests/core/io/test_stream_peer_buffer.h | 5 +- engine/tests/core/io/test_stream_peer_gzip.h | 195 + engine/tests/core/io/test_tcp_server.h | 5 +- engine/tests/core/io/test_udp_server.h | 5 +- engine/tests/core/io/test_xml_parser.h | 5 +- engine/tests/core/math/test_aabb.h | 37 +- engine/tests/core/math/test_astar.h | 9 +- engine/tests/core/math/test_basis.h | 23 +- engine/tests/core/math/test_color.h | 29 +- engine/tests/core/math/test_expression.h | 35 +- engine/tests/core/math/test_geometry_2d.h | 38 +- engine/tests/core/math/test_geometry_3d.h | 29 +- engine/tests/core/math/test_math_funcs.h | 93 +- engine/tests/core/math/test_plane.h | 53 +- engine/tests/core/math/test_projection.h | 200 +- engine/tests/core/math/test_quaternion.h | 73 +- .../core/math/test_random_number_generator.h | 5 +- engine/tests/core/math/test_rect2.h | 23 +- engine/tests/core/math/test_rect2i.h | 19 +- engine/tests/core/math/test_transform_2d.h | 45 +- engine/tests/core/math/test_transform_3d.h | 25 +- engine/tests/core/math/test_triangle_mesh.h | 82 + engine/tests/core/math/test_vector2.h | 119 +- engine/tests/core/math/test_vector2i.h | 41 +- engine/tests/core/math/test_vector3.h | 130 +- engine/tests/core/math/test_vector3i.h | 41 +- engine/tests/core/math/test_vector4.h | 83 +- engine/tests/core/math/test_vector4i.h | 41 +- engine/tests/core/object/test_class_db.h | 18 +- engine/tests/core/object/test_method_bind.h | 7 +- engine/tests/core/object/test_object.h | 98 +- engine/tests/core/object/test_undo_redo.h | 5 +- engine/tests/core/os/test_os.h | 5 +- engine/tests/core/string/test_fuzzy_search.h | 5 +- engine/tests/core/string/test_node_path.h | 5 +- engine/tests/core/string/test_string.h | 248 +- engine/tests/core/string/test_translation.h | 5 +- .../core/string/test_translation_server.h | 5 +- engine/tests/core/templates/test_a_hash_map.h | 9 +- .../tests/core/templates/test_command_queue.h | 5 +- engine/tests/core/templates/test_hash_map.h | 5 +- engine/tests/core/templates/test_hash_set.h | 5 +- engine/tests/core/templates/test_list.h | 5 +- .../tests/core/templates/test_local_vector.h | 22 +- engine/tests/core/templates/test_lru.h | 5 +- .../tests/core/templates/test_oa_hash_map.h | 5 +- .../tests/core/templates/test_paged_array.h | 5 +- engine/tests/core/templates/test_rid.h | 14 +- engine/tests/core/templates/test_span.h | 70 + engine/tests/core/templates/test_vector.h | 5 +- engine/tests/core/test_crypto.h | 9 +- engine/tests/core/test_hashing_context.h | 5 +- engine/tests/core/test_time.h | 5 +- .../core/threads/test_worker_thread_pool.h | 5 +- engine/tests/core/variant/test_array.h | 80 +- engine/tests/core/variant/test_callable.h | 11 +- engine/tests/core/variant/test_dictionary.h | 67 +- engine/tests/core/variant/test_variant.h | 23 +- .../tests/core/variant/test_variant_utility.h | 16 +- engine/tests/create_test.py | 6 +- .../tests/data/exactly_4096_bytes_fastlz.bin | Bin 0 -> 93 bytes engine/tests/display_server_mock.h | 7 +- engine/tests/python_build/conftest.py | 26 - .../fixtures/gles3/vertex_fragment.out | 64 + .../gles3/vertex_fragment_expected_full.glsl | 74 - .../gles3/vertex_fragment_expected_parts.json | 53 - ...compute_expected_full.glsl => compute.out} | 5 - .../fixtures/glsl/compute_expected_parts.json | 3 - ...expected_full.glsl => vertex_fragment.out} | 5 - .../glsl/vertex_fragment_expected_parts.json | 3 - ...compute_expected_full.glsl => compute.out} | 13 +- .../rd_glsl/compute_expected_parts.json | 28 - ...expected_full.glsl => vertex_fragment.out} | 12 +- .../vertex_fragment_expected_parts.json | 40 - .../tests/python_build/test_gles3_builder.py | 31 - .../tests/python_build/test_glsl_builder.py | 37 - .../tests/python_build/validate_builders.py | 63 + engine/tests/scene/test_animation.h | 5 +- engine/tests/scene/test_arraymesh.h | 13 +- engine/tests/scene/test_audio_stream_wav.h | 7 +- engine/tests/scene/test_bit_map.h | 5 +- engine/tests/scene/test_button.h | 4 +- engine/tests/scene/test_camera_2d.h | 9 +- engine/tests/scene/test_camera_3d.h | 38 +- engine/tests/scene/test_code_edit.h | 76 +- engine/tests/scene/test_color_picker.h | 5 +- engine/tests/scene/test_control.h | 851 +- engine/tests/scene/test_curve.h | 5 +- engine/tests/scene/test_curve_2d.h | 5 +- engine/tests/scene/test_curve_3d.h | 5 +- engine/tests/scene/test_fontfile.h | 53 +- engine/tests/scene/test_gltf_document.h | 5 +- engine/tests/scene/test_gradient.h | 5 +- engine/tests/scene/test_gradient_texture.h | 5 +- engine/tests/scene/test_graph_node.h | 5 +- engine/tests/scene/test_height_map_shape_3d.h | 5 +- engine/tests/scene/test_image_texture.h | 5 +- engine/tests/scene/test_image_texture_3d.h | 5 +- .../tests/scene/test_instance_placeholder.h | 14 +- engine/tests/scene/test_navigation_agent_2d.h | 9 +- engine/tests/scene/test_navigation_agent_3d.h | 9 +- .../tests/scene/test_navigation_obstacle_2d.h | 9 +- .../tests/scene/test_navigation_obstacle_3d.h | 9 +- .../tests/scene/test_navigation_region_2d.h | 9 +- .../tests/scene/test_navigation_region_3d.h | 9 +- engine/tests/scene/test_node.h | 5 +- engine/tests/scene/test_node_2d.h | 5 +- engine/tests/scene/test_option_button.h | 32 +- engine/tests/scene/test_packed_scene.h | 5 +- engine/tests/scene/test_parallax_2d.h | 5 +- engine/tests/scene/test_path_2d.h | 5 +- engine/tests/scene/test_path_3d.h | 5 +- engine/tests/scene/test_path_follow_2d.h | 5 +- engine/tests/scene/test_path_follow_3d.h | 71 +- engine/tests/scene/test_physics_material.h | 5 +- engine/tests/scene/test_primitives.h | 5 +- engine/tests/scene/test_skeleton_3d.h | 5 +- engine/tests/scene/test_sky.h | 5 +- engine/tests/scene/test_split_container.h | 9 +- engine/tests/scene/test_sprite_frames.h | 5 +- engine/tests/scene/test_style_box_texture.h | 5 +- engine/tests/scene/test_tab_bar.h | 5 +- engine/tests/scene/test_tab_container.h | 5 +- engine/tests/scene/test_text_edit.h | 53 +- .../tests/scene/test_texture_progress_bar.h | 13 +- engine/tests/scene/test_theme.h | 5 +- engine/tests/scene/test_timer.h | 21 +- engine/tests/scene/test_tree.h | 5 +- engine/tests/scene/test_viewport.h | 60 +- engine/tests/scene/test_visual_shader.h | 5 +- engine/tests/scene/test_window.h | 5 +- .../rendering/test_shader_preprocessor.h | 5 +- engine/tests/servers/test_nav_heap.h | 196 + .../tests/servers/test_navigation_server_2d.h | 730 +- .../tests/servers/test_navigation_server_3d.h | 282 +- engine/tests/servers/test_text_server.h | 55 +- engine/tests/test_macros.h | 29 +- engine/tests/test_main.cpp | 104 +- engine/tests/test_main.h | 5 +- engine/tests/test_tools.h | 5 +- engine/tests/test_utils.h | 5 +- engine/tests/test_validate_testing.h | 9 +- engine/thirdparty/README.md | 49 +- engine/thirdparty/accesskit/LICENSE-MIT | 23 + .../thirdparty/accesskit/include/accesskit.h | 2352 + .../clipper2/include/clipper2/clipper.core.h | 72 +- .../include/clipper2/clipper.engine.h | 34 +- .../include/clipper2/clipper.export.h | 488 +- .../clipper2/include/clipper2/clipper.h | 35 +- .../include/clipper2/clipper.minkowski.h | 21 +- .../include/clipper2/clipper.offset.h | 11 +- .../include/clipper2/clipper.rectclip.h | 8 +- .../include/clipper2/clipper.version.h | 2 +- .../patches/0001-disable-exceptions.patch | 14 +- ...ch => 0002-llvm-disable-int128-math.patch} | 16 +- .../clipper2/src/clipper.engine.cpp | 110 +- .../clipper2/src/clipper.offset.cpp | 153 +- .../clipper2/src/clipper.rectclip.cpp | 31 +- .../include/freetype/config/ftconfig.h | 2 +- .../include/freetype/config/ftheader.h | 2 +- .../include/freetype/config/ftoption.h | 18 +- .../include/freetype/config/ftstdlib.h | 2 +- .../include/freetype/config/integer-types.h | 2 +- .../include/freetype/config/mac-support.h | 2 +- .../include/freetype/config/public-macros.h | 2 +- .../freetype/include/freetype/freetype.h | 118 +- .../freetype/include/freetype/ftadvanc.h | 2 +- .../freetype/include/freetype/ftbbox.h | 2 +- .../freetype/include/freetype/ftbdf.h | 2 +- .../freetype/include/freetype/ftbitmap.h | 2 +- .../freetype/include/freetype/ftbzip2.h | 2 +- .../freetype/include/freetype/ftcache.h | 2 +- .../freetype/include/freetype/ftcid.h | 2 +- .../freetype/include/freetype/ftcolor.h | 2 +- .../freetype/include/freetype/ftdriver.h | 76 +- .../freetype/include/freetype/fterrdef.h | 2 +- .../freetype/include/freetype/fterrors.h | 2 +- .../freetype/include/freetype/ftfntfmt.h | 2 +- .../freetype/include/freetype/ftgasp.h | 2 +- .../freetype/include/freetype/ftglyph.h | 2 +- .../freetype/include/freetype/ftgxval.h | 2 +- .../freetype/include/freetype/ftgzip.h | 2 +- .../freetype/include/freetype/ftimage.h | 29 +- .../freetype/include/freetype/ftincrem.h | 2 +- .../freetype/include/freetype/ftlcdfil.h | 2 +- .../freetype/include/freetype/ftlist.h | 2 +- .../freetype/include/freetype/ftlogging.h | 2 +- .../freetype/include/freetype/ftlzw.h | 2 +- .../freetype/include/freetype/ftmac.h | 2 +- .../freetype/include/freetype/ftmm.h | 33 +- .../freetype/include/freetype/ftmodapi.h | 2 +- .../freetype/include/freetype/ftmoderr.h | 2 +- .../freetype/include/freetype/ftotval.h | 2 +- .../freetype/include/freetype/ftoutln.h | 4 +- .../freetype/include/freetype/ftparams.h | 2 +- .../freetype/include/freetype/ftpfr.h | 2 +- .../freetype/include/freetype/ftrender.h | 2 +- .../freetype/include/freetype/ftsizes.h | 2 +- .../freetype/include/freetype/ftsnames.h | 2 +- .../freetype/include/freetype/ftstroke.h | 2 +- .../freetype/include/freetype/ftsynth.h | 2 +- .../freetype/include/freetype/ftsystem.h | 2 +- .../freetype/include/freetype/fttrigon.h | 2 +- .../freetype/include/freetype/fttypes.h | 2 +- .../freetype/include/freetype/ftwinfnt.h | 2 +- .../include/freetype/internal/autohint.h | 2 +- .../include/freetype/internal/cffotypes.h | 2 +- .../include/freetype/internal/cfftypes.h | 10 +- .../freetype/internal/compiler-macros.h | 2 +- .../include/freetype/internal/ftcalc.h | 21 +- .../include/freetype/internal/ftdebug.h | 2 +- .../include/freetype/internal/ftdrv.h | 2 +- .../include/freetype/internal/ftgloadr.h | 2 +- .../include/freetype/internal/ftmemory.h | 9 +- .../include/freetype/internal/ftmmtypes.h | 2 +- .../include/freetype/internal/ftobjs.h | 8 +- .../include/freetype/internal/ftpsprop.h | 2 +- .../include/freetype/internal/ftrfork.h | 2 +- .../include/freetype/internal/ftserv.h | 2 +- .../include/freetype/internal/ftstream.h | 2 +- .../include/freetype/internal/fttrace.h | 3 +- .../include/freetype/internal/ftvalid.h | 2 +- .../include/freetype/internal/psaux.h | 21 +- .../include/freetype/internal/pshints.h | 2 +- .../freetype/internal/services/svbdf.h | 2 +- .../freetype/internal/services/svcfftl.h | 2 +- .../freetype/internal/services/svcid.h | 2 +- .../freetype/internal/services/svfntfmt.h | 2 +- .../freetype/internal/services/svgldict.h | 2 +- .../freetype/internal/services/svgxval.h | 2 +- .../freetype/internal/services/svkern.h | 2 +- .../freetype/internal/services/svmetric.h | 2 +- .../include/freetype/internal/services/svmm.h | 2 +- .../freetype/internal/services/svotval.h | 2 +- .../freetype/internal/services/svpfr.h | 2 +- .../freetype/internal/services/svpostnm.h | 2 +- .../freetype/internal/services/svprop.h | 2 +- .../freetype/internal/services/svpscmap.h | 2 +- .../freetype/internal/services/svpsinfo.h | 2 +- .../freetype/internal/services/svsfnt.h | 2 +- .../freetype/internal/services/svttcmap.h | 2 +- .../freetype/internal/services/svtteng.h | 2 +- .../freetype/internal/services/svttglyf.h | 2 +- .../freetype/internal/services/svwinfnt.h | 2 +- .../freetype/include/freetype/internal/sfnt.h | 9 +- .../include/freetype/internal/svginterface.h | 2 +- .../include/freetype/internal/t1types.h | 52 +- .../include/freetype/internal/tttypes.h | 12 +- .../include/freetype/internal/wofftypes.h | 2 +- .../freetype/include/freetype/otsvg.h | 2 +- .../freetype/include/freetype/t1tables.h | 60 +- .../freetype/include/freetype/ttnameid.h | 2 +- .../freetype/include/freetype/tttables.h | 7 +- .../freetype/include/freetype/tttags.h | 2 +- engine/thirdparty/freetype/include/ft2build.h | 2 +- .../thirdparty/freetype/src/autofit/afblue.c | 2 +- .../freetype/src/autofit/afblue.cin | 2 +- .../thirdparty/freetype/src/autofit/afblue.h | 2 +- .../freetype/src/autofit/afblue.hin | 2 +- .../thirdparty/freetype/src/autofit/afcjk.c | 2 +- .../thirdparty/freetype/src/autofit/afcjk.h | 4 +- .../thirdparty/freetype/src/autofit/afcover.h | 2 +- .../thirdparty/freetype/src/autofit/afdummy.c | 2 +- .../thirdparty/freetype/src/autofit/afdummy.h | 2 +- .../freetype/src/autofit/aferrors.h | 2 +- .../freetype/src/autofit/afglobal.c | 2 +- .../freetype/src/autofit/afglobal.h | 2 +- .../thirdparty/freetype/src/autofit/afhints.c | 18 +- .../thirdparty/freetype/src/autofit/afhints.h | 2 +- .../thirdparty/freetype/src/autofit/afindic.c | 2 +- .../thirdparty/freetype/src/autofit/afindic.h | 2 +- .../thirdparty/freetype/src/autofit/aflatin.c | 9 +- .../thirdparty/freetype/src/autofit/aflatin.h | 4 +- .../freetype/src/autofit/afloader.c | 2 +- .../freetype/src/autofit/afloader.h | 2 +- .../freetype/src/autofit/afmodule.c | 4 +- .../freetype/src/autofit/afmodule.h | 2 +- .../freetype/src/autofit/afranges.c | 2 +- .../freetype/src/autofit/afranges.h | 2 +- .../freetype/src/autofit/afscript.h | 2 +- .../freetype/src/autofit/afshaper.c | 2 +- .../freetype/src/autofit/afshaper.h | 2 +- .../freetype/src/autofit/afstyles.h | 2 +- .../thirdparty/freetype/src/autofit/aftypes.h | 2 +- .../freetype/src/autofit/afws-decl.h | 2 +- .../freetype/src/autofit/afws-iter.h | 2 +- .../thirdparty/freetype/src/autofit/autofit.c | 2 +- .../thirdparty/freetype/src/base/ftadvanc.c | 2 +- engine/thirdparty/freetype/src/base/ftbase.c | 2 +- engine/thirdparty/freetype/src/base/ftbase.h | 2 +- engine/thirdparty/freetype/src/base/ftbbox.c | 4 +- engine/thirdparty/freetype/src/base/ftbdf.c | 2 +- .../thirdparty/freetype/src/base/ftbitmap.c | 2 +- engine/thirdparty/freetype/src/base/ftcalc.c | 169 +- engine/thirdparty/freetype/src/base/ftcid.c | 2 +- engine/thirdparty/freetype/src/base/ftcolor.c | 2 +- .../thirdparty/freetype/src/base/ftdbgmem.c | 2 +- engine/thirdparty/freetype/src/base/ftdebug.c | 2 +- .../thirdparty/freetype/src/base/fterrors.c | 2 +- .../thirdparty/freetype/src/base/ftfntfmt.c | 2 +- .../thirdparty/freetype/src/base/ftfstype.c | 2 +- engine/thirdparty/freetype/src/base/ftgasp.c | 2 +- .../thirdparty/freetype/src/base/ftgloadr.c | 35 +- engine/thirdparty/freetype/src/base/ftglyph.c | 2 +- engine/thirdparty/freetype/src/base/ftgxval.c | 2 +- engine/thirdparty/freetype/src/base/ftinit.c | 2 +- .../thirdparty/freetype/src/base/ftlcdfil.c | 2 +- engine/thirdparty/freetype/src/base/ftmac.c | 21 +- engine/thirdparty/freetype/src/base/ftmm.c | 2 +- engine/thirdparty/freetype/src/base/ftobjs.c | 9 +- engine/thirdparty/freetype/src/base/ftotval.c | 2 +- engine/thirdparty/freetype/src/base/ftoutln.c | 18 +- .../thirdparty/freetype/src/base/ftpatent.c | 2 +- engine/thirdparty/freetype/src/base/ftpfr.c | 2 +- .../thirdparty/freetype/src/base/ftpsprop.c | 2 +- engine/thirdparty/freetype/src/base/ftrfork.c | 2 +- .../thirdparty/freetype/src/base/ftsnames.c | 2 +- .../thirdparty/freetype/src/base/ftstream.c | 8 +- .../thirdparty/freetype/src/base/ftstroke.c | 16 +- engine/thirdparty/freetype/src/base/ftsynth.c | 2 +- .../thirdparty/freetype/src/base/ftsystem.c | 2 +- .../thirdparty/freetype/src/base/fttrigon.c | 2 +- engine/thirdparty/freetype/src/base/fttype1.c | 2 +- engine/thirdparty/freetype/src/base/ftutil.c | 2 +- .../thirdparty/freetype/src/base/ftwinfnt.c | 2 +- engine/thirdparty/freetype/src/bdf/bdfdrivr.c | 4 +- engine/thirdparty/freetype/src/bdf/bdflib.c | 15 +- .../thirdparty/freetype/src/bzip2/ftbzip2.c | 2 +- .../thirdparty/freetype/src/cache/ftcache.c | 2 +- .../thirdparty/freetype/src/cache/ftcbasic.c | 120 +- .../thirdparty/freetype/src/cache/ftccache.c | 35 +- .../thirdparty/freetype/src/cache/ftccache.h | 6 +- .../thirdparty/freetype/src/cache/ftccback.h | 12 +- .../thirdparty/freetype/src/cache/ftccmap.c | 4 +- .../thirdparty/freetype/src/cache/ftcerror.h | 2 +- .../thirdparty/freetype/src/cache/ftcglyph.c | 6 +- .../thirdparty/freetype/src/cache/ftcglyph.h | 3 +- .../thirdparty/freetype/src/cache/ftcimage.c | 14 +- .../thirdparty/freetype/src/cache/ftcimage.h | 2 +- .../thirdparty/freetype/src/cache/ftcmanag.c | 57 +- .../thirdparty/freetype/src/cache/ftcmanag.h | 2 +- engine/thirdparty/freetype/src/cache/ftcmru.c | 69 +- engine/thirdparty/freetype/src/cache/ftcmru.h | 8 +- .../thirdparty/freetype/src/cache/ftcsbits.c | 5 +- .../thirdparty/freetype/src/cache/ftcsbits.h | 2 +- engine/thirdparty/freetype/src/cff/cff.c | 2 +- engine/thirdparty/freetype/src/cff/cffcmap.c | 2 +- engine/thirdparty/freetype/src/cff/cffcmap.h | 2 +- engine/thirdparty/freetype/src/cff/cffdrivr.c | 2 +- engine/thirdparty/freetype/src/cff/cffdrivr.h | 2 +- engine/thirdparty/freetype/src/cff/cfferrs.h | 2 +- engine/thirdparty/freetype/src/cff/cffgload.c | 2 +- engine/thirdparty/freetype/src/cff/cffgload.h | 2 +- engine/thirdparty/freetype/src/cff/cffload.c | 77 +- engine/thirdparty/freetype/src/cff/cffload.h | 2 +- engine/thirdparty/freetype/src/cff/cffobjs.c | 95 +- engine/thirdparty/freetype/src/cff/cffobjs.h | 2 +- engine/thirdparty/freetype/src/cff/cffparse.c | 97 +- engine/thirdparty/freetype/src/cff/cffparse.h | 3 +- engine/thirdparty/freetype/src/cff/cfftoken.h | 74 +- engine/thirdparty/freetype/src/cid/ciderrs.h | 2 +- engine/thirdparty/freetype/src/cid/cidgload.c | 2 +- engine/thirdparty/freetype/src/cid/cidgload.h | 2 +- engine/thirdparty/freetype/src/cid/cidload.c | 41 +- engine/thirdparty/freetype/src/cid/cidload.h | 2 +- engine/thirdparty/freetype/src/cid/cidobjs.c | 2 +- engine/thirdparty/freetype/src/cid/cidobjs.h | 2 +- engine/thirdparty/freetype/src/cid/cidparse.c | 69 +- engine/thirdparty/freetype/src/cid/cidparse.h | 2 +- engine/thirdparty/freetype/src/cid/cidriver.c | 2 +- engine/thirdparty/freetype/src/cid/cidriver.h | 2 +- engine/thirdparty/freetype/src/cid/cidtoken.h | 2 +- engine/thirdparty/freetype/src/cid/type1cid.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvalid.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvalid.h | 2 +- .../thirdparty/freetype/src/gxvalid/gxvbsln.c | 2 +- .../freetype/src/gxvalid/gxvcommn.c | 2 +- .../freetype/src/gxvalid/gxvcommn.h | 5 +- .../freetype/src/gxvalid/gxverror.h | 2 +- .../thirdparty/freetype/src/gxvalid/gxvfeat.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvfeat.h | 2 +- .../thirdparty/freetype/src/gxvalid/gxvfgen.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvjust.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvkern.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvlcar.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmod.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmod.h | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmort.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmort.h | 2 +- .../freetype/src/gxvalid/gxvmort0.c | 2 +- .../freetype/src/gxvalid/gxvmort1.c | 2 +- .../freetype/src/gxvalid/gxvmort2.c | 2 +- .../freetype/src/gxvalid/gxvmort4.c | 2 +- .../freetype/src/gxvalid/gxvmort5.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmorx.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvmorx.h | 2 +- .../freetype/src/gxvalid/gxvmorx0.c | 2 +- .../freetype/src/gxvalid/gxvmorx1.c | 2 +- .../freetype/src/gxvalid/gxvmorx2.c | 2 +- .../freetype/src/gxvalid/gxvmorx4.c | 2 +- .../freetype/src/gxvalid/gxvmorx5.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvopbd.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvprop.c | 2 +- .../thirdparty/freetype/src/gxvalid/gxvtrak.c | 2 +- engine/thirdparty/freetype/src/gzip/ftgzip.c | 2 +- engine/thirdparty/freetype/src/lzw/ftlzw.c | 2 +- engine/thirdparty/freetype/src/lzw/ftzopen.c | 2 +- engine/thirdparty/freetype/src/lzw/ftzopen.h | 2 +- .../thirdparty/freetype/src/otvalid/otvalid.c | 2 +- .../thirdparty/freetype/src/otvalid/otvalid.h | 2 +- .../thirdparty/freetype/src/otvalid/otvbase.c | 2 +- .../freetype/src/otvalid/otvcommn.c | 2 +- .../freetype/src/otvalid/otvcommn.h | 2 +- .../freetype/src/otvalid/otverror.h | 2 +- .../thirdparty/freetype/src/otvalid/otvgdef.c | 2 +- .../thirdparty/freetype/src/otvalid/otvgpos.c | 2 +- .../thirdparty/freetype/src/otvalid/otvgpos.h | 2 +- .../thirdparty/freetype/src/otvalid/otvgsub.c | 2 +- .../thirdparty/freetype/src/otvalid/otvjstf.c | 2 +- .../thirdparty/freetype/src/otvalid/otvmath.c | 2 +- .../thirdparty/freetype/src/otvalid/otvmod.c | 2 +- .../thirdparty/freetype/src/otvalid/otvmod.h | 2 +- engine/thirdparty/freetype/src/pcf/pcfdrivr.c | 2 +- engine/thirdparty/freetype/src/pcf/pcfutil.c | 2 +- engine/thirdparty/freetype/src/pfr/pfr.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrcmap.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrcmap.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrdrivr.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrdrivr.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrerror.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrgload.c | 10 +- engine/thirdparty/freetype/src/pfr/pfrgload.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrload.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrload.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrobjs.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrobjs.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrsbit.c | 2 +- engine/thirdparty/freetype/src/pfr/pfrsbit.h | 2 +- engine/thirdparty/freetype/src/pfr/pfrtypes.h | 2 +- .../thirdparty/freetype/src/psaux/afmparse.c | 2 +- .../thirdparty/freetype/src/psaux/afmparse.h | 2 +- .../thirdparty/freetype/src/psaux/cffdecode.c | 20 +- .../thirdparty/freetype/src/psaux/cffdecode.h | 2 +- engine/thirdparty/freetype/src/psaux/psaux.c | 2 +- .../thirdparty/freetype/src/psaux/psauxerr.h | 2 +- .../thirdparty/freetype/src/psaux/psauxmod.c | 2 +- .../thirdparty/freetype/src/psaux/psauxmod.h | 2 +- .../thirdparty/freetype/src/psaux/psblues.c | 48 +- engine/thirdparty/freetype/src/psaux/psconv.c | 2 +- engine/thirdparty/freetype/src/psaux/psconv.h | 2 +- engine/thirdparty/freetype/src/psaux/psft.c | 16 +- engine/thirdparty/freetype/src/psaux/psft.h | 8 +- .../thirdparty/freetype/src/psaux/psintrp.c | 27 +- engine/thirdparty/freetype/src/psaux/psobjs.c | 46 +- engine/thirdparty/freetype/src/psaux/psobjs.h | 2 +- engine/thirdparty/freetype/src/psaux/t1cmap.c | 2 +- engine/thirdparty/freetype/src/psaux/t1cmap.h | 2 +- .../thirdparty/freetype/src/psaux/t1decode.c | 2 +- .../thirdparty/freetype/src/psaux/t1decode.h | 2 +- .../freetype/src/pshinter/pshalgo.c | 10 +- .../freetype/src/pshinter/pshalgo.h | 2 +- .../freetype/src/pshinter/pshglob.c | 2 +- .../freetype/src/pshinter/pshglob.h | 2 +- .../freetype/src/pshinter/pshinter.c | 2 +- .../thirdparty/freetype/src/pshinter/pshmod.c | 2 +- .../thirdparty/freetype/src/pshinter/pshmod.h | 2 +- .../freetype/src/pshinter/pshnterr.h | 2 +- .../thirdparty/freetype/src/pshinter/pshrec.c | 4 +- .../thirdparty/freetype/src/pshinter/pshrec.h | 2 +- .../freetype/src/psnames/psmodule.c | 2 +- .../freetype/src/psnames/psmodule.h | 2 +- .../freetype/src/psnames/psnamerr.h | 2 +- .../thirdparty/freetype/src/psnames/psnames.c | 2 +- .../freetype/src/psnames/pstables.h | 2 +- .../thirdparty/freetype/src/raster/ftmisc.h | 23 +- .../thirdparty/freetype/src/raster/ftraster.c | 1868 +- .../thirdparty/freetype/src/raster/ftraster.h | 2 +- .../thirdparty/freetype/src/raster/ftrend1.c | 2 +- .../thirdparty/freetype/src/raster/ftrend1.h | 2 +- .../thirdparty/freetype/src/raster/raster.c | 2 +- .../thirdparty/freetype/src/raster/rasterrs.h | 2 +- engine/thirdparty/freetype/src/sdf/ftbsdf.c | 2 +- engine/thirdparty/freetype/src/sdf/ftsdf.c | 4 +- engine/thirdparty/freetype/src/sdf/ftsdf.h | 2 +- .../thirdparty/freetype/src/sdf/ftsdfcommon.c | 45 +- .../thirdparty/freetype/src/sdf/ftsdfcommon.h | 5 +- .../thirdparty/freetype/src/sdf/ftsdferrs.h | 2 +- .../thirdparty/freetype/src/sdf/ftsdfrend.c | 2 +- .../thirdparty/freetype/src/sdf/ftsdfrend.h | 2 +- engine/thirdparty/freetype/src/sdf/sdf.c | 2 +- engine/thirdparty/freetype/src/sfnt/pngshim.c | 2 +- engine/thirdparty/freetype/src/sfnt/pngshim.h | 2 +- .../thirdparty/freetype/src/sfnt/sfdriver.c | 17 +- .../thirdparty/freetype/src/sfnt/sfdriver.h | 2 +- .../thirdparty/freetype/src/sfnt/sferrors.h | 2 +- engine/thirdparty/freetype/src/sfnt/sfnt.c | 3 +- engine/thirdparty/freetype/src/sfnt/sfobjs.c | 21 +- engine/thirdparty/freetype/src/sfnt/sfobjs.h | 2 +- engine/thirdparty/freetype/src/sfnt/sfwoff.c | 20 +- engine/thirdparty/freetype/src/sfnt/sfwoff.h | 2 +- engine/thirdparty/freetype/src/sfnt/sfwoff2.c | 54 +- engine/thirdparty/freetype/src/sfnt/sfwoff2.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttbdf.c | 4 +- engine/thirdparty/freetype/src/sfnt/ttbdf.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttcmap.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttcmap.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttcmapc.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttcolr.c | 38 +- engine/thirdparty/freetype/src/sfnt/ttcolr.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttcpal.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttcpal.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttgpos.c | 598 + engine/thirdparty/freetype/src/sfnt/ttgpos.h | 53 + engine/thirdparty/freetype/src/sfnt/ttkern.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttkern.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttload.c | 4 +- engine/thirdparty/freetype/src/sfnt/ttload.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttmtx.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttmtx.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttpost.c | 50 +- engine/thirdparty/freetype/src/sfnt/ttpost.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttsbit.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttsbit.h | 2 +- engine/thirdparty/freetype/src/sfnt/ttsvg.c | 2 +- engine/thirdparty/freetype/src/sfnt/ttsvg.h | 2 +- .../thirdparty/freetype/src/sfnt/woff2tags.c | 2 +- .../thirdparty/freetype/src/sfnt/woff2tags.h | 2 +- .../thirdparty/freetype/src/smooth/ftgrays.c | 461 +- .../thirdparty/freetype/src/smooth/ftgrays.h | 2 +- .../thirdparty/freetype/src/smooth/ftsmerrs.h | 2 +- .../thirdparty/freetype/src/smooth/ftsmooth.c | 2 +- .../thirdparty/freetype/src/smooth/ftsmooth.h | 2 +- .../thirdparty/freetype/src/smooth/smooth.c | 2 +- engine/thirdparty/freetype/src/svg/ftsvg.c | 2 +- engine/thirdparty/freetype/src/svg/ftsvg.h | 2 +- engine/thirdparty/freetype/src/svg/svg.c | 2 +- engine/thirdparty/freetype/src/svg/svgtypes.h | 2 +- .../freetype/src/truetype/truetype.c | 2 +- .../freetype/src/truetype/ttdriver.c | 17 +- .../freetype/src/truetype/ttdriver.h | 2 +- .../freetype/src/truetype/tterrors.h | 2 +- .../freetype/src/truetype/ttgload.c | 51 +- .../freetype/src/truetype/ttgload.h | 2 +- .../freetype/src/truetype/ttgxvar.c | 419 +- .../freetype/src/truetype/ttgxvar.h | 2 +- .../freetype/src/truetype/ttinterp.c | 16 +- .../freetype/src/truetype/ttinterp.h | 2 +- .../thirdparty/freetype/src/truetype/ttobjs.c | 52 +- .../thirdparty/freetype/src/truetype/ttobjs.h | 4 +- .../freetype/src/truetype/ttpload.c | 2 +- .../freetype/src/truetype/ttpload.h | 2 +- engine/thirdparty/freetype/src/type1/t1afm.c | 2 +- engine/thirdparty/freetype/src/type1/t1afm.h | 2 +- .../thirdparty/freetype/src/type1/t1driver.c | 10 +- .../thirdparty/freetype/src/type1/t1driver.h | 2 +- .../thirdparty/freetype/src/type1/t1errors.h | 2 +- .../thirdparty/freetype/src/type1/t1gload.c | 2 +- .../thirdparty/freetype/src/type1/t1gload.h | 2 +- engine/thirdparty/freetype/src/type1/t1load.c | 28 +- engine/thirdparty/freetype/src/type1/t1load.h | 2 +- engine/thirdparty/freetype/src/type1/t1objs.c | 2 +- engine/thirdparty/freetype/src/type1/t1objs.h | 2 +- .../thirdparty/freetype/src/type1/t1parse.c | 2 +- .../thirdparty/freetype/src/type1/t1parse.h | 2 +- .../thirdparty/freetype/src/type1/t1tokens.h | 2 +- engine/thirdparty/freetype/src/type1/type1.c | 2 +- .../thirdparty/freetype/src/type42/t42drivr.c | 2 +- .../thirdparty/freetype/src/type42/t42drivr.h | 2 +- .../thirdparty/freetype/src/type42/t42error.h | 2 +- .../thirdparty/freetype/src/type42/t42objs.c | 2 +- .../thirdparty/freetype/src/type42/t42objs.h | 2 +- .../thirdparty/freetype/src/type42/t42parse.c | 22 +- .../thirdparty/freetype/src/type42/t42parse.h | 2 +- .../thirdparty/freetype/src/type42/t42types.h | 2 +- .../thirdparty/freetype/src/type42/type42.c | 2 +- .../freetype/src/winfonts/fnterrs.h | 2 +- .../thirdparty/freetype/src/winfonts/winfnt.c | 8 +- .../thirdparty/freetype/src/winfonts/winfnt.h | 2 +- .../harfbuzz/src/OT/Color/CBDT/CBDT.hh | 4 +- .../harfbuzz/src/OT/Color/COLR/COLR.hh | 69 +- .../harfbuzz/src/OT/Color/CPAL/CPAL.hh | 8 + .../harfbuzz/src/OT/Layout/Common/Coverage.hh | 22 + .../src/OT/Layout/Common/CoverageFormat1.hh | 2 + .../src/OT/Layout/Common/CoverageFormat2.hh | 2 + .../src/OT/Layout/GPOS/PairPosFormat1.hh | 44 +- .../src/OT/Layout/GPOS/PairPosFormat2.hh | 58 +- .../src/OT/Layout/GPOS/SinglePosFormat1.hh | 2 +- .../src/OT/Layout/GPOS/SinglePosFormat2.hh | 2 +- .../OT/Layout/GSUB/AlternateSubstFormat1.hh | 2 +- .../OT/Layout/GSUB/LigatureSubstFormat1.hh | 43 +- .../OT/Layout/GSUB/MultipleSubstFormat1.hh | 2 +- .../GSUB/ReverseChainSingleSubstFormat1.hh | 2 +- .../src/OT/Layout/GSUB/SingleSubstFormat1.hh | 2 +- .../src/OT/Layout/GSUB/SingleSubstFormat2.hh | 2 +- .../harfbuzz/src/OT/Layout/types.hh | 3 + .../harfbuzz/src/OT/Var/VARC/VARC.cc | 108 +- .../harfbuzz/src/OT/Var/VARC/VARC.hh | 163 +- .../harfbuzz/src/OT/Var/VARC/coord-setter.hh | 40 +- .../harfbuzz/src/OT/glyf/CompositeGlyph.hh | 2 +- .../thirdparty/harfbuzz/src/OT/glyf/Glyph.hh | 66 +- .../harfbuzz/src/OT/glyf/SimpleGlyph.hh | 18 +- .../thirdparty/harfbuzz/src/OT/glyf/glyf.hh | 163 +- .../harfbuzz/src/OT/glyf/path-builder.hh | 106 +- .../thirdparty/harfbuzz/src/OT/name/name.hh | 10 +- .../harfbuzz/src/hb-aat-layout-common.hh | 243 +- .../harfbuzz/src/hb-aat-layout-kerx-table.hh | 124 +- .../harfbuzz/src/hb-aat-layout-morx-table.hh | 399 +- .../harfbuzz/src/hb-aat-layout-trak-table.hh | 178 +- .../thirdparty/harfbuzz/src/hb-aat-layout.cc | 46 +- .../thirdparty/harfbuzz/src/hb-aat-layout.hh | 8 +- engine/thirdparty/harfbuzz/src/hb-aat-map.cc | 15 +- engine/thirdparty/harfbuzz/src/hb-algs.hh | 10 +- engine/thirdparty/harfbuzz/src/hb-array.hh | 3 +- engine/thirdparty/harfbuzz/src/hb-atomic.hh | 1 + engine/thirdparty/harfbuzz/src/hb-bit-page.hh | 55 +- .../harfbuzz/src/hb-bit-set-invertible.hh | 4 + engine/thirdparty/harfbuzz/src/hb-bit-set.hh | 65 +- .../src/hb-buffer-deserialize-json.hh | 508 +- engine/thirdparty/harfbuzz/src/hb-buffer.cc | 8 +- engine/thirdparty/harfbuzz/src/hb-buffer.hh | 17 +- engine/thirdparty/harfbuzz/src/hb-cairo.cc | 12 +- .../harfbuzz/src/hb-cff-interp-common.hh | 2 +- engine/thirdparty/harfbuzz/src/hb-common.cc | 3 + engine/thirdparty/harfbuzz/src/hb-config.hh | 3 +- .../harfbuzz/src/hb-coretext-font.cc | 108 +- .../harfbuzz/src/hb-coretext-shape.cc | 48 +- engine/thirdparty/harfbuzz/src/hb-decycler.hh | 164 + .../thirdparty/harfbuzz/src/hb-directwrite.cc | 115 +- .../thirdparty/harfbuzz/src/hb-directwrite.h | 16 +- engine/thirdparty/harfbuzz/src/hb-face.cc | 49 +- engine/thirdparty/harfbuzz/src/hb-face.h | 9 +- engine/thirdparty/harfbuzz/src/hb-ft-colr.hh | 32 +- engine/thirdparty/harfbuzz/src/hb-ft.cc | 91 +- engine/thirdparty/harfbuzz/src/hb-ft.h | 9 +- engine/thirdparty/harfbuzz/src/hb-geometry.hh | 9 + engine/thirdparty/harfbuzz/src/hb-null.hh | 2 +- .../thirdparty/harfbuzz/src/hb-open-type.hh | 194 +- .../harfbuzz/src/hb-ot-cff1-table.cc | 9 - .../harfbuzz/src/hb-ot-cff1-table.hh | 1 - .../harfbuzz/src/hb-ot-cff2-table.cc | 9 - .../harfbuzz/src/hb-ot-cff2-table.hh | 1 - .../harfbuzz/src/hb-ot-cmap-table.hh | 4 + .../harfbuzz/src/hb-ot-face-table-list.hh | 5 +- engine/thirdparty/harfbuzz/src/hb-ot-face.cc | 1 + engine/thirdparty/harfbuzz/src/hb-ot-font.cc | 60 +- .../harfbuzz/src/hb-ot-hdmx-table.hh | 2 +- .../harfbuzz/src/hb-ot-hmtx-table.hh | 2 +- .../harfbuzz/src/hb-ot-kern-table.hh | 4 +- .../harfbuzz/src/hb-ot-layout-base-table.hh | 2 +- .../harfbuzz/src/hb-ot-layout-common.hh | 63 +- .../harfbuzz/src/hb-ot-layout-gsubgpos.hh | 173 +- .../thirdparty/harfbuzz/src/hb-ot-layout.cc | 30 +- .../thirdparty/harfbuzz/src/hb-ot-layout.hh | 10 +- engine/thirdparty/harfbuzz/src/hb-ot-map.cc | 14 + engine/thirdparty/harfbuzz/src/hb-ot-map.hh | 3 + .../harfbuzz/src/hb-ot-os2-table.hh | 4 +- engine/thirdparty/harfbuzz/src/hb-ot-shape.cc | 51 +- engine/thirdparty/harfbuzz/src/hb-ot-shape.h | 6 + engine/thirdparty/harfbuzz/src/hb-ot-shape.hh | 15 +- .../src/hb-ot-shaper-arabic-fallback.hh | 2 + .../src/hb-ot-shaper-indic-machine.hh | 1279 +- .../harfbuzz/src/hb-ot-shaper-indic-table.cc | 11 +- .../src/hb-ot-shaper-myanmar-machine.hh | 694 +- .../harfbuzz/src/hb-ot-shaper-use-machine.hh | 1256 +- .../src/hb-ot-shaper-vowel-constraints.cc | 2 +- .../harfbuzz/src/hb-ot-tag-table.hh | 213 +- .../harfbuzz/src/hb-ot-var-common.hh | 64 +- .../harfbuzz/src/hb-ot-var-cvar-table.hh | 26 +- .../harfbuzz/src/hb-ot-var-gvar-table.hh | 142 +- engine/thirdparty/harfbuzz/src/hb-paint.h | 2 +- engine/thirdparty/harfbuzz/src/hb-sanitize.hh | 4 +- .../thirdparty/harfbuzz/src/hb-serialize.hh | 27 +- .../thirdparty/harfbuzz/src/hb-set-digest.hh | 169 +- engine/thirdparty/harfbuzz/src/hb-set.hh | 4 + .../thirdparty/harfbuzz/src/hb-shape-plan.cc | 10 +- engine/thirdparty/harfbuzz/src/hb-shape.h | 2 + .../harfbuzz/src/hb-subset-cff-common.hh | 2 +- .../thirdparty/harfbuzz/src/hb-subset-cff1.cc | 2 +- .../harfbuzz/src/hb-subset-input.cc | 139 +- .../thirdparty/harfbuzz/src/hb-subset-plan.cc | 18 +- .../thirdparty/harfbuzz/src/hb-subset-plan.hh | 26 +- .../harfbuzz/src/hb-subset-repacker.h | 81 - ...set-repacker.cc => hb-subset-serialize.cc} | 33 +- .../harfbuzz/src/hb-subset-serialize.h | 83 + engine/thirdparty/harfbuzz/src/hb-subset.cc | 4 +- engine/thirdparty/harfbuzz/src/hb-subset.h | 12 + engine/thirdparty/harfbuzz/src/hb-utf.hh | 6 +- engine/thirdparty/harfbuzz/src/hb-vector.hh | 99 +- engine/thirdparty/harfbuzz/src/hb-version.h | 4 +- engine/thirdparty/harfbuzz/src/hb.hh | 5 +- engine/thirdparty/icu4c/LICENSE | 2 +- engine/thirdparty/icu4c/common/brkiter.cpp | 59 +- engine/thirdparty/icu4c/common/charstr.cpp | 11 +- engine/thirdparty/icu4c/common/charstr.h | 3 +- .../icu4c/common/localefallback_data.h | 2311 +- engine/thirdparty/icu4c/common/locbased.cpp | 72 +- engine/thirdparty/icu4c/common/locbased.h | 64 +- .../thirdparty/icu4c/common/locdispnames.cpp | 8 +- engine/thirdparty/icu4c/common/locid.cpp | 43 +- engine/thirdparty/icu4c/common/loclikely.cpp | 16 +- .../icu4c/common/loclikelysubtags.cpp | 2 +- engine/thirdparty/icu4c/common/locresdata.cpp | 3 + engine/thirdparty/icu4c/common/punycode.cpp | 2 +- engine/thirdparty/icu4c/common/putil.cpp | 2 +- engine/thirdparty/icu4c/common/rbbinode.cpp | 118 +- engine/thirdparty/icu4c/common/rbbinode.h | 8 +- engine/thirdparty/icu4c/common/rbbiscan.cpp | 15 +- engine/thirdparty/icu4c/common/rbbisetb.cpp | 12 +- engine/thirdparty/icu4c/common/rbbitblb.cpp | 28 +- engine/thirdparty/icu4c/common/resbund.cpp | 2 +- engine/thirdparty/icu4c/common/ucnvmbcs.cpp | 5 +- engine/thirdparty/icu4c/common/ucurr.cpp | 17 +- engine/thirdparty/icu4c/common/uloc.cpp | 551 +- engine/thirdparty/icu4c/common/uloc_tag.cpp | 25 +- engine/thirdparty/icu4c/common/ulocale.cpp | 5 +- engine/thirdparty/icu4c/common/ulocimp.h | 32 +- engine/thirdparty/icu4c/common/umapfile.cpp | 7 +- .../thirdparty/icu4c/common/unicode/brkiter.h | 8 +- .../icu4c/common/unicode/char16ptr.h | 77 +- .../thirdparty/icu4c/common/unicode/locid.h | 9 +- .../thirdparty/icu4c/common/unicode/resbund.h | 2 +- .../thirdparty/icu4c/common/unicode/uchar.h | 48 +- .../thirdparty/icu4c/common/unicode/uniset.h | 11 +- engine/thirdparty/icu4c/common/unicode/uset.h | 92 +- engine/thirdparty/icu4c/common/unicode/utf8.h | 4 +- .../thirdparty/icu4c/common/unicode/utypes.h | 3 +- .../thirdparty/icu4c/common/unicode/uvernum.h | 10 +- .../icu4c/common/unicode/uversion.h | 19 +- engine/thirdparty/icu4c/common/unistr.cpp | 7 + engine/thirdparty/icu4c/common/uresbund.cpp | 8 +- engine/thirdparty/icu4c/common/uscript.cpp | 3 + engine/thirdparty/icu4c/common/ushape.cpp | 5 + engine/thirdparty/icu4c/common/usprep.cpp | 2 +- engine/thirdparty/icu4c/common/utf_impl.cpp | 6 +- engine/thirdparty/icu4c/common/utypes.cpp | 3 +- engine/thirdparty/icu4c/i18n/scriptset.cpp | 6 +- engine/thirdparty/icu4c/i18n/scriptset.h | 2 +- engine/thirdparty/icu4c/i18n/ucln_in.h | 2 + engine/thirdparty/icu4c/icudt_godot.dat | Bin 4805392 -> 4784480 bytes .../thirdparty/jolt_physics/Jolt/Core/Array.h | 117 +- .../thirdparty/jolt_physics/Jolt/Core/Color.h | 2 +- .../thirdparty/jolt_physics/Jolt/Core/Core.h | 22 +- .../jolt_physics/Jolt/Core/FPException.h | 26 +- .../jolt_physics/Jolt/Core/HashTable.h | 70 +- .../jolt_physics/Jolt/Core/Profiler.cpp | 327 +- .../Jolt/Core/STLLocalAllocator.h | 3 +- .../jolt_physics/Jolt/Core/Semaphore.cpp | 64 +- .../jolt_physics/Jolt/Core/Semaphore.h | 55 +- .../jolt_physics/Jolt/Core/StreamIn.h | 3 +- .../jolt_physics/Jolt/Core/TempAllocator.h | 14 +- .../jolt_physics/Jolt/Geometry/AABox.h | 5 +- .../Jolt/Geometry/EPAPenetrationDepth.h | 6 +- .../Jolt/Geometry/GJKClosestPoint.h | 1 - .../jolt_physics/Jolt/Geometry/OrientedBox.h | 2 +- .../jolt_physics/Jolt/Geometry/RayAABox.h | 2 +- .../jolt_physics/Jolt/Geometry/RayTriangle.h | 6 +- .../thirdparty/jolt_physics/Jolt/Jolt.natvis | 2 +- .../thirdparty/jolt_physics/Jolt/Math/DVec3.h | 3 + .../jolt_physics/Jolt/Math/DVec3.inl | 7 +- .../Jolt/Math/EigenValueSymmetric.h | 2 +- .../jolt_physics/Jolt/Math/HalfFloat.h | 4 + .../thirdparty/jolt_physics/Jolt/Math/Math.h | 3 + .../thirdparty/jolt_physics/Jolt/Math/Vec3.h | 3 + .../jolt_physics/Jolt/Math/Vec3.inl | 7 +- .../thirdparty/jolt_physics/Jolt/Math/Vec4.h | 3 + .../jolt_physics/Jolt/Math/Vec4.inl | 15 +- .../jolt_physics/Jolt/Physics/Body/Body.cpp | 6 +- .../jolt_physics/Jolt/Physics/Body/Body.h | 25 +- .../jolt_physics/Jolt/Physics/Body/BodyID.h | 9 +- .../Jolt/Physics/Body/BodyInterface.cpp | 64 +- .../Jolt/Physics/Body/BodyInterface.h | 7 + .../Jolt/Physics/Body/BodyManager.cpp | 10 +- .../Jolt/Physics/Body/MotionProperties.inl | 4 +- .../Jolt/Physics/Character/Character.cpp | 18 +- .../Jolt/Physics/Character/Character.h | 4 + .../Jolt/Physics/Character/CharacterID.h | 98 + .../Physics/Character/CharacterVirtual.cpp | 257 +- .../Jolt/Physics/Character/CharacterVirtual.h | 163 +- .../BroadPhase/BroadPhaseQuadTree.cpp | 26 +- .../Physics/Collision/BroadPhase/QuadTree.cpp | 110 +- .../Physics/Collision/BroadPhase/QuadTree.h | 5 +- .../Collision/CollideConvexVsTriangles.cpp | 15 +- .../Collision/CollideShapeVsShapePerLeaf.h | 93 + .../Physics/Collision/CollisionCollector.h | 6 +- .../Collision/CollisionCollectorImpl.h | 85 + .../Jolt/Physics/Collision/CollisionGroup.cpp | 2 + .../Jolt/Physics/Collision/CollisionGroup.h | 3 + .../Collision/InternalEdgeRemovingCollector.h | 11 + .../Collision/ManifoldBetweenTwoFaces.cpp | 39 +- .../Collision/ManifoldBetweenTwoFaces.h | 4 +- .../Physics/Collision/NarrowPhaseQuery.cpp | 103 +- .../Physics/Collision/Shape/CompoundShape.cpp | 7 +- .../Physics/Collision/Shape/CompoundShape.h | 8 +- .../Physics/Collision/Shape/ConvexHullShape.h | 2 +- .../Physics/Collision/Shape/ConvexShape.cpp | 31 +- .../Physics/Collision/Shape/CylinderShape.cpp | 24 +- .../Collision/Shape/HeightFieldShape.cpp | 244 +- .../Collision/Shape/HeightFieldShape.h | 8 +- .../Physics/Collision/Shape/MeshShape.cpp | 40 +- .../Jolt/Physics/Collision/Shape/MeshShape.h | 11 + .../Collision/Shape/MutableCompoundShape.cpp | 34 +- .../Collision/Shape/MutableCompoundShape.h | 9 +- .../Jolt/Physics/Collision/Shape/PlaneShape.h | 6 +- .../Physics/Collision/Shape/ScaleHelpers.h | 2 +- .../Jolt/Physics/Collision/Shape/Shape.cpp | 2 +- .../Physics/Collision/Shape/SphereShape.cpp | 2 +- .../Collision/Shape/StaticCompoundShape.cpp | 2 +- .../Collision/Shape/TaperedCapsuleShape.cpp | 2 +- .../Collision/Shape/TaperedCylinderShape.cpp | 46 +- .../Physics/Collision/Shape/TriangleShape.cpp | 5 +- .../Constraints/ContactConstraintManager.cpp | 21 +- .../Constraints/ContactConstraintManager.h | 8 + .../Physics/Constraints/HingeConstraint.cpp | 2 +- .../Jolt/Physics/PhysicsScene.cpp | 2 +- .../Jolt/Physics/PhysicsSettings.h | 4 +- .../Jolt/Physics/PhysicsSystem.cpp | 67 +- .../jolt_physics/Jolt/Physics/PhysicsSystem.h | 34 + .../SoftBody/SoftBodyMotionProperties.cpp | 32 +- .../SoftBody/SoftBodyMotionProperties.h | 3 +- .../Jolt/Physics/SoftBody/SoftBodyShape.cpp | 3 + .../SoftBody/SoftBodySharedSettings.cpp | 147 + .../Physics/SoftBody/SoftBodySharedSettings.h | 6 + .../Jolt/Physics/Vehicle/VehicleAntiRollBar.h | 2 + .../Vehicle/VehicleCollisionTester.cpp | 4 +- .../Physics/Vehicle/VehicleConstraint.cpp | 37 +- .../Jolt/Physics/Vehicle/VehicleConstraint.h | 8 +- .../Jolt/Physics/Vehicle/VehicleController.h | 2 +- .../jolt_physics/Jolt/RegisterTypes.cpp | 8 + .../Jolt/Renderer/DebugRenderer.cpp | 2 +- .../Jolt/Renderer/DebugRenderer.h | 2 +- .../Jolt/TriangleGrouper/TriangleGrouper.h | 27 - .../TriangleGrouperClosestCentroid.cpp | 95 - .../TriangleGrouperClosestCentroid.h | 21 - .../TriangleGrouper/TriangleGrouperMorton.cpp | 49 - .../TriangleGrouper/TriangleGrouperMorton.h | 20 - .../TriangleSplitter/TriangleSplitter.cpp | 30 +- .../TriangleSplitterBinning.cpp | 13 +- .../TriangleSplitterFixedLeafSize.cpp | 170 - .../TriangleSplitterFixedLeafSize.h | 55 - .../TriangleSplitterLongestAxis.cpp | 31 - .../TriangleSplitterLongestAxis.h | 28 - .../TriangleSplitter/TriangleSplitterMean.cpp | 11 +- .../TriangleSplitterMorton.cpp | 63 - .../TriangleSplitter/TriangleSplitterMorton.h | 32 - engine/thirdparty/libpng/png.c | 1266 +- engine/thirdparty/libpng/png.h | 117 +- engine/thirdparty/libpng/pngconf.h | 2 +- engine/thirdparty/libpng/pngerror.c | 26 +- engine/thirdparty/libpng/pngget.c | 287 +- engine/thirdparty/libpng/pnginfo.h | 48 +- engine/thirdparty/libpng/pnglibconf.h | 8 +- engine/thirdparty/libpng/pngmem.c | 37 +- engine/thirdparty/libpng/pngpread.c | 176 +- engine/thirdparty/libpng/pngpriv.h | 424 +- engine/thirdparty/libpng/pngread.c | 359 +- engine/thirdparty/libpng/pngrtran.c | 337 +- engine/thirdparty/libpng/pngrutil.c | 1856 +- engine/thirdparty/libpng/pngset.c | 266 +- engine/thirdparty/libpng/pngstruct.h | 96 +- engine/thirdparty/libpng/pngwrite.c | 62 +- engine/thirdparty/libpng/pngwutil.c | 52 +- .../mbedtls/include/mbedtls/build_info.h | 8 +- .../mbedtls/include/mbedtls/check_config.h | 8 + .../mbedtls/config_adjust_legacy_crypto.h | 75 +- .../mbedtls/config_adjust_legacy_from_psa.h | 19 - .../config_adjust_psa_superset_legacy.h | 7 - .../mbedtls/include/mbedtls/debug.h | 6 +- .../mbedtls/include/mbedtls/entropy.h | 5 +- .../mbedtls/include/mbedtls/error.h | 2 +- .../thirdparty/mbedtls/include/mbedtls/gcm.h | 23 +- .../mbedtls/include/mbedtls/mbedtls_config.h | 129 +- .../mbedtls/include/mbedtls/net_sockets.h | 2 +- .../mbedtls/include/mbedtls/psa_util.h | 19 + .../thirdparty/mbedtls/include/mbedtls/ssl.h | 124 +- .../mbedtls/include/mbedtls/threading.h | 2 +- .../mbedtls/include/psa/crypto_config.h | 14 - .../mbedtls/include/psa/crypto_extra.h | 39 + .../mbedtls/include/psa/crypto_sizes.h | 25 + engine/thirdparty/mbedtls/library/aesni.c | 8 +- .../thirdparty/mbedtls/library/bignum_core.c | 26 +- .../thirdparty/mbedtls/library/bignum_core.h | 26 +- engine/thirdparty/mbedtls/library/ccm.c | 3 +- .../mbedtls/library/constant_time_impl.h | 17 +- engine/thirdparty/mbedtls/library/ecp.c | 2 +- engine/thirdparty/mbedtls/library/error.c | 6 +- .../thirdparty/mbedtls/library/net_sockets.c | 12 +- engine/thirdparty/mbedtls/library/pk.c | 4 - .../thirdparty/mbedtls/library/psa_crypto.c | 182 +- .../mbedtls/library/psa_crypto_cipher.c | 3 - .../mbedtls/library/psa_crypto_core.h | 16 +- .../library/psa_crypto_driver_wrappers.h | 4 +- .../mbedtls/library/psa_crypto_ecp.c | 36 +- .../library/psa_crypto_slot_management.c | 4 +- .../mbedtls/library/psa_crypto_storage.h | 11 +- engine/thirdparty/mbedtls/library/psa_util.c | 6 + .../thirdparty/mbedtls/library/ssl_client.c | 18 +- .../library/ssl_debug_helpers_generated.c | 2 +- engine/thirdparty/mbedtls/library/ssl_misc.h | 17 +- engine/thirdparty/mbedtls/library/ssl_msg.c | 195 +- engine/thirdparty/mbedtls/library/ssl_tls.c | 101 +- .../mbedtls/library/ssl_tls12_client.c | 2 +- .../mbedtls/library/ssl_tls13_client.c | 1 + .../mbedtls/library/ssl_tls13_server.c | 5 +- engine/thirdparty/mbedtls/library/threading.c | 2 +- .../mbedtls/library/version_features.c | 6 + ...ment-incoming-tls-handshake-messages.patch | 373 - engine/thirdparty/misc/yuv2rgb.h | 3 +- engine/thirdparty/pcre2/AUTHORS | 36 - engine/thirdparty/pcre2/AUTHORS.md | 200 + .../thirdparty/pcre2/{LICENCE => LICENCE.md} | 75 +- .../allocator_src/sljitExecAllocatorApple.c | 6 +- .../allocator_src/sljitExecAllocatorCore.c | 23 +- .../allocator_src/sljitExecAllocatorFreeBSD.c | 0 .../allocator_src/sljitExecAllocatorPosix.c | 0 .../allocator_src/sljitExecAllocatorWindows.c | 0 .../sljitProtExecAllocatorNetBSD.c | 0 .../sljitProtExecAllocatorPosix.c | 0 .../allocator_src/sljitWXExecAllocatorPosix.c | 0 .../sljitWXExecAllocatorWindows.c | 0 .../sljit/sljit_src}/sljitConfig.h | 22 +- .../sljit/sljit_src}/sljitConfigCPU.h | 2 +- .../sljit/sljit_src}/sljitConfigInternal.h | 181 +- .../sljit => deps/sljit/sljit_src}/sljitLir.c | 1170 +- .../sljit => deps/sljit/sljit_src}/sljitLir.h | 553 +- .../sljit/sljit_src}/sljitNativeARM_32.c | 861 +- .../sljit/sljit_src}/sljitNativeARM_64.c | 831 +- .../sljit/sljit_src}/sljitNativeARM_T2_32.c | 775 +- .../sljit_src}/sljitNativeLOONGARCH_64.c | 1218 +- .../sljit/sljit_src}/sljitNativeMIPS_32.c | 6 +- .../sljit/sljit_src}/sljitNativeMIPS_64.c | 6 +- .../sljit/sljit_src}/sljitNativeMIPS_common.c | 418 +- .../sljit/sljit_src}/sljitNativePPC_32.c | 0 .../sljit/sljit_src}/sljitNativePPC_64.c | 0 .../sljit/sljit_src}/sljitNativePPC_common.c | 727 +- .../sljit/sljit_src}/sljitNativeRISCV_32.c | 0 .../sljit/sljit_src}/sljitNativeRISCV_64.c | 0 .../sljit_src}/sljitNativeRISCV_common.c | 1434 +- .../sljit/sljit_src}/sljitNativeS390X.c | 683 +- .../sljit/sljit_src}/sljitNativeX86_32.c | 138 +- .../sljit/sljit_src}/sljitNativeX86_64.c | 177 +- .../sljit/sljit_src}/sljitNativeX86_common.c | 1495 +- .../deps/sljit/sljit_src/sljitSerialize.c | 516 + .../sljit/sljit_src}/sljitUtils.c | 0 engine/thirdparty/pcre2/src/config.h | 54 +- engine/thirdparty/pcre2/src/pcre2.h | 72 +- .../thirdparty/pcre2/src/pcre2_auto_possess.c | 143 +- engine/thirdparty/pcre2/src/pcre2_chkdint.c | 6 +- engine/thirdparty/pcre2/src/pcre2_compile.c | 3195 +- engine/thirdparty/pcre2/src/pcre2_compile.h | 280 + .../pcre2/src/pcre2_compile_class.c | 2737 ++ engine/thirdparty/pcre2/src/pcre2_config.c | 4 +- engine/thirdparty/pcre2/src/pcre2_context.c | 66 +- engine/thirdparty/pcre2/src/pcre2_convert.c | 18 +- engine/thirdparty/pcre2/src/pcre2_dfa_match.c | 107 +- engine/thirdparty/pcre2/src/pcre2_error.c | 33 +- engine/thirdparty/pcre2/src/pcre2_extuni.c | 30 +- .../thirdparty/pcre2/src/pcre2_find_bracket.c | 15 +- engine/thirdparty/pcre2/src/pcre2_internal.h | 363 +- .../thirdparty/pcre2/src/pcre2_intmodedep.h | 66 +- .../thirdparty/pcre2/src/pcre2_jit_char_inc.h | 2280 + .../thirdparty/pcre2/src/pcre2_jit_compile.c | 3673 +- engine/thirdparty/pcre2/src/pcre2_jit_match.c | 2 +- engine/thirdparty/pcre2/src/pcre2_jit_misc.c | 4 +- .../thirdparty/pcre2/src/pcre2_jit_neon_inc.h | 10 +- .../thirdparty/pcre2/src/pcre2_jit_simd_inc.h | 115 +- .../thirdparty/pcre2/src/pcre2_maketables.c | 10 +- engine/thirdparty/pcre2/src/pcre2_match.c | 617 +- .../thirdparty/pcre2/src/pcre2_match_data.c | 8 +- engine/thirdparty/pcre2/src/pcre2_ord2utf.c | 2 +- .../thirdparty/pcre2/src/pcre2_pattern_info.c | 14 +- engine/thirdparty/pcre2/src/pcre2_serialize.c | 36 +- engine/thirdparty/pcre2/src/pcre2_study.c | 238 +- .../thirdparty/pcre2/src/pcre2_substitute.c | 1028 +- engine/thirdparty/pcre2/src/pcre2_substring.c | 4 +- engine/thirdparty/pcre2/src/pcre2_tables.c | 12 +- engine/thirdparty/pcre2/src/pcre2_ucd.c | 8658 ++-- engine/thirdparty/pcre2/src/pcre2_ucp.h | 62 +- engine/thirdparty/pcre2/src/pcre2_ucptables.c | 777 +- engine/thirdparty/pcre2/src/pcre2_util.h | 132 + engine/thirdparty/pcre2/src/pcre2_xclass.c | 395 +- .../common/gamesdk_common.h | 7 +- .../thirdparty/swappy-frame-pacing/swappyVk.h | 105 +- .../swappy-frame-pacing/swappy_common.h | 193 +- engine/thirdparty/thorvg/inc/config.h | 2 +- .../0002-png-explicit-variable-scope.patch | 13 + .../src/loaders/external_png/tvgPngLoader.cpp | 2 +- .../loaders/external_webp/tvgWebpLoader.cpp | 2 +- .../thorvg/src/loaders/jpg/tvgJpgLoader.cpp | 1 + .../thorvg/src/loaders/svg/tvgSvgLoader.cpp | 68 +- .../src/loaders/svg/tvgSvgLoaderCommon.h | 9 + .../src/loaders/svg/tvgSvgSceneBuilder.cpp | 45 +- .../thorvg/src/loaders/svg/tvgXmlParser.cpp | 8 + .../src/renderer/sw_engine/tvgSwCommon.h | 12 +- .../src/renderer/sw_engine/tvgSwMath.cpp | 8 +- .../renderer/sw_engine/tvgSwPostEffect.cpp | 18 +- .../src/renderer/sw_engine/tvgSwRaster.cpp | 10 +- .../src/renderer/sw_engine/tvgSwRenderer.cpp | 4 +- .../src/renderer/sw_engine/tvgSwRle.cpp | 4 +- .../src/renderer/sw_engine/tvgSwShape.cpp | 6 +- .../thorvg/src/renderer/tvgLoadModule.h | 21 +- .../thorvg/src/renderer/tvgLoader.cpp | 33 +- .../thorvg/src/renderer/tvgRender.h | 2 + .../thorvg/src/renderer/tvgTaskScheduler.cpp | 13 +- .../thorvg/src/renderer/tvgTaskScheduler.h | 1 - .../thorvg/src/renderer/tvgText.cpp | 6 +- .../thirdparty/thorvg/src/renderer/tvgText.h | 18 +- engine/thirdparty/thorvg/update-thorvg.sh | 2 +- engine/thirdparty/ufbx/ufbx.c | 546 +- engine/thirdparty/ufbx/ufbx.h | 168 +- engine/version.py | 6 +- {engine/modules => modules}/PROJECT/SCsub | 0 {engine/modules => modules}/PROJECT/config.py | 0 {engine/modules => modules}/PROJECT/macros.h | 0 .../PROJECT/register_types.cpp | 0 .../PROJECT/register_types.h | 0 5136 files changed, 225275 insertions(+), 64485 deletions(-) create mode 100644 .gitmodules create mode 100644 engine/core/templates/bit_field.h create mode 100644 engine/core/templates/span.h create mode 100644 engine/doc/classes/FoldableContainer.xml create mode 100644 engine/doc/classes/FoldableGroup.xml create mode 100644 engine/doc/translations/ru.po create mode 100644 engine/drivers/accesskit/SCsub create mode 100644 engine/drivers/accesskit/accessibility_driver_accesskit.cpp create mode 100644 engine/drivers/accesskit/accessibility_driver_accesskit.h create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.c create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.h create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.c create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.h create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.c create mode 100644 engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.h create mode 100644 engine/drivers/apple/thread_apple.cpp create mode 100644 engine/drivers/apple/thread_apple.h rename engine/drivers/coremidi/{midi_driver_coremidi.cpp => midi_driver_coremidi.mm} (98%) create mode 100644 engine/editor/export/editor_export_platform.compat.inc create mode 100644 engine/editor/gui/touch_actions_panel.cpp create mode 100644 engine/editor/gui/touch_actions_panel.h create mode 100644 engine/editor/icons/AudioMute.svg create mode 100644 engine/editor/icons/DragHandle.svg create mode 100644 engine/editor/icons/FoldableContainer.svg create mode 100644 engine/editor/icons/GuiArrowUp.svg create mode 100644 engine/editor/icons/Orientation.svg create mode 100644 engine/editor/icons/Redo.svg create mode 100644 engine/editor/plugins/camera_2d_editor_plugin.cpp create mode 100644 engine/editor/plugins/camera_2d_editor_plugin.h create mode 100644 engine/editor/project_upgrade_tool.cpp rename engine/editor/{surface_upgrade_tool.h => project_upgrade_tool.h} (72%) delete mode 100644 engine/editor/surface_upgrade_tool.cpp create mode 100644 engine/editor/translations/editor/tok.po delete mode 100644 engine/editor/uid_upgrade_tool.cpp rename engine/misc/extension_api_validation/{4.3-stable.expected => 4.3-stable_4.4-stable.expected} (98%) create mode 100644 engine/misc/extension_api_validation/4.4-stable.expected create mode 100644 engine/misc/msvs/nmake.substitution.props create mode 100755 engine/misc/scripts/char_range_fetch.py create mode 100755 engine/misc/scripts/purge_cache.py create mode 100644 engine/modules/dds/dds_enums.h create mode 100644 engine/modules/dds/image_saver_dds.cpp create mode 100644 engine/modules/dds/image_saver_dds.h create mode 100644 engine/modules/dds/tests/test_dds.h create mode 100644 engine/modules/gdscript/tests/scripts/completion/common/invalid_super_call_1.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/common/invalid_super_call_1.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/common/invalid_super_call_2.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/common/invalid_super_call_2.gd rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered/local_infered.cfg => local_inferred/local_inferred.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered/local_infered.gd => local_inferred/local_inferred.gd} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered_scene/class_local_infered_scene.cfg => local_inferred_scene/class_local_inferred_scene.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered_scene/class_local_infered_scene.gd => local_inferred_scene/class_local_inferred_scene.gd} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered_scene/native_local_infered_scene.cfg => local_inferred_scene/native_local_inferred_scene.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{local_infered_scene/native_local_infered_scene.gd => local_inferred_scene/native_local_inferred_scene.gd} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered/member_infered.cfg => member_inferred/member_inferred.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered/member_infered.gd => member_inferred/member_inferred.gd} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered_scene/class_member_infered_scene.cfg => member_inferred_scene/class_member_inferred_scene.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered_scene/class_member_infered_scene.gd => member_inferred_scene/class_member_inferred_scene.gd} (66%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered_scene/native_member_infered_scene.cfg => member_inferred_scene/native_member_inferred_scene.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/get_node/{member_infered_scene/native_member_infered_scene.gd => member_inferred_scene/native_member_inferred_scene.gd} (55%) create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/builtin_complete_braces.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/builtin_complete_braces.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/builtin_incomplete_braces.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/builtin_incomplete_braces.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_callable_arg_0.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_callable_arg_0.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_callable_arg_1.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_callable_arg_1.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_variant_arg_0.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/local_method_variant_arg_0.gd create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/native.cfg create mode 100644 engine/modules/gdscript/tests/scripts/completion/no_parenthesis_when_callable_is_expected/native.gd rename engine/modules/gdscript/tests/scripts/completion/types/local/{infered.cfg => inferred.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/types/local/{infered.gd => inferred.gd} (100%) rename engine/modules/gdscript/tests/scripts/completion/types/member/{infered.cfg => inferred.cfg} (100%) rename engine/modules/gdscript/tests/scripts/completion/types/member/{infered.gd => inferred.gd} (100%) create mode 100644 engine/modules/gdscript/tests/scripts/lsp/first_line_class_name.gd create mode 100644 engine/modules/gdscript/tests/scripts/runtime/errors/reload_suspended_function.notest.gd create mode 100644 engine/modules/gdscript/tests/scripts/runtime/errors/reload_suspended_function.out create mode 100644 engine/modules/gdscript/tests/scripts/runtime/errors/reload_suspended_function_helper.notest.gd create mode 100644 engine/modules/gdscript/tests/scripts/runtime/features/callv_readonly_array.gd create mode 100644 engine/modules/gdscript/tests/scripts/runtime/features/callv_readonly_array.out create mode 100644 engine/modules/jolt_physics/misc/jolt_math_funcs.cpp create mode 100644 engine/modules/jolt_physics/misc/jolt_math_funcs.h create mode 100644 engine/modules/jsonrpc/jsonrpc.compat.inc create mode 100644 engine/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/NestedInGenericTest.cs create mode 100644 engine/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties2_ScriptPropertyDefVal.generated.cs create mode 100644 engine/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/GenericClass(Of T).NestedClass_ScriptMethods.generated.cs create mode 100644 engine/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties2.cs create mode 100644 engine/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/NestedInGeneric.cs create mode 100644 engine/modules/multiplayer/tests/test_multiplayer_spawner.h delete mode 100644 engine/modules/navigation/2d/godot_navigation_server_2d.cpp create mode 100644 engine/modules/navigation_2d/2d/godot_navigation_server_2d.cpp rename engine/modules/{navigation => navigation_2d}/2d/godot_navigation_server_2d.h (65%) create mode 100644 engine/modules/navigation_2d/2d/nav_base_iteration_2d.h create mode 100644 engine/modules/navigation_2d/2d/nav_map_builder_2d.cpp create mode 100644 engine/modules/navigation_2d/2d/nav_map_builder_2d.h create mode 100644 engine/modules/navigation_2d/2d/nav_map_iteration_2d.h rename engine/modules/{navigation => navigation_2d}/2d/nav_mesh_generator_2d.cpp (98%) rename engine/modules/{navigation => navigation_2d}/2d/nav_mesh_generator_2d.h (98%) create mode 100644 engine/modules/navigation_2d/2d/nav_mesh_queries_2d.cpp create mode 100644 engine/modules/navigation_2d/2d/nav_mesh_queries_2d.h create mode 100644 engine/modules/navigation_2d/2d/nav_region_iteration_2d.h create mode 100644 engine/modules/navigation_2d/SCsub create mode 100644 engine/modules/navigation_2d/config.py create mode 100644 engine/modules/navigation_2d/nav_agent_2d.cpp create mode 100644 engine/modules/navigation_2d/nav_agent_2d.h rename engine/modules/{navigation/nav_base.h => navigation_2d/nav_base_2d.h} (92%) create mode 100644 engine/modules/navigation_2d/nav_link_2d.cpp create mode 100644 engine/modules/navigation_2d/nav_link_2d.h create mode 100644 engine/modules/navigation_2d/nav_map_2d.cpp create mode 100644 engine/modules/navigation_2d/nav_map_2d.h create mode 100644 engine/modules/navigation_2d/nav_obstacle_2d.cpp create mode 100644 engine/modules/navigation_2d/nav_obstacle_2d.h create mode 100644 engine/modules/navigation_2d/nav_region_2d.cpp create mode 100644 engine/modules/navigation_2d/nav_region_2d.h rename engine/modules/{navigation/nav_rid.h => navigation_2d/nav_rid_2d.h} (94%) create mode 100644 engine/modules/navigation_2d/nav_utils_2d.h create mode 100644 engine/modules/navigation_2d/register_types.cpp rename engine/modules/{navigation => navigation_2d}/register_types.h (90%) create mode 100644 engine/modules/navigation_2d/triangle2.cpp create mode 100644 engine/modules/navigation_2d/triangle2.h rename engine/modules/{navigation => navigation_3d}/3d/godot_navigation_server_3d.cpp (78%) rename engine/modules/{navigation => navigation_3d}/3d/godot_navigation_server_3d.h (95%) rename engine/modules/{navigation => navigation_3d}/3d/nav_base_iteration_3d.h (93%) rename engine/modules/{navigation => navigation_3d}/3d/nav_map_builder_3d.cpp (68%) rename engine/modules/{navigation => navigation_3d}/3d/nav_map_builder_3d.h (84%) rename engine/modules/{navigation => navigation_3d}/3d/nav_map_iteration_3d.h (77%) rename engine/modules/{navigation => navigation_3d}/3d/nav_mesh_generator_3d.cpp (99%) rename engine/modules/{navigation => navigation_3d}/3d/nav_mesh_generator_3d.h (97%) rename engine/modules/{navigation => navigation_3d}/3d/nav_mesh_queries_3d.cpp (72%) rename engine/modules/{navigation => navigation_3d}/3d/nav_mesh_queries_3d.h (70%) rename engine/modules/{navigation => navigation_3d}/3d/nav_region_iteration_3d.h (89%) rename engine/modules/{navigation => navigation_3d}/3d/navigation_mesh_generator.cpp (99%) rename engine/modules/{navigation => navigation_3d}/3d/navigation_mesh_generator.h (94%) rename engine/modules/{navigation => navigation_3d}/SCsub (69%) rename engine/modules/{navigation => navigation_3d}/config.py (63%) rename engine/modules/{navigation => navigation_3d}/editor/navigation_mesh_editor_plugin.cpp (97%) rename engine/modules/{navigation => navigation_3d}/editor/navigation_mesh_editor_plugin.h (93%) rename engine/modules/{navigation/nav_agent.cpp => navigation_3d/nav_agent_3d.cpp} (87%) rename engine/modules/{navigation/nav_agent.h => navigation_3d/nav_agent_3d.h} (93%) create mode 100644 engine/modules/navigation_3d/nav_base_3d.h rename engine/modules/{navigation/nav_link.cpp => navigation_3d/nav_link_3d.cpp} (83%) rename engine/modules/{navigation/nav_link.h => navigation_3d/nav_link_3d.h} (87%) rename engine/modules/{navigation/nav_map.cpp => navigation_3d/nav_map_3d.cpp} (73%) rename engine/modules/{navigation/nav_map.h => navigation_3d/nav_map_3d.h} (72%) rename engine/modules/{navigation/nav_obstacle.cpp => navigation_3d/nav_obstacle_3d.cpp} (82%) rename engine/modules/{navigation/nav_obstacle.h => navigation_3d/nav_obstacle_3d.h} (87%) rename engine/modules/{navigation/nav_region.cpp => navigation_3d/nav_region_3d.cpp} (86%) rename engine/modules/{navigation/nav_region.h => navigation_3d/nav_region_3d.h} (85%) create mode 100644 engine/modules/navigation_3d/nav_rid_3d.h rename engine/modules/{navigation/nav_utils.h => navigation_3d/nav_utils_3d.h} (63%) rename engine/modules/{navigation => navigation_3d}/register_types.cpp (87%) create mode 100644 engine/modules/navigation_3d/register_types.h create mode 100644 engine/modules/openxr/doc_classes/OpenXRExtensionWrapper.xml create mode 100644 engine/modules/openxr/doc_classes/OpenXRFutureExtension.xml create mode 100644 engine/modules/openxr/doc_classes/OpenXRFutureResult.xml rename engine/modules/openxr/extensions/{openxr_extension_wrapper_extension.cpp => openxr_extension_wrapper.cpp} (62%) create mode 100644 engine/modules/openxr/extensions/openxr_future_extension.cpp create mode 100644 engine/modules/openxr/extensions/openxr_future_extension.h create mode 100644 engine/modules/openxr/extensions/openxr_performance_settings_extension.cpp rename engine/{editor/uid_upgrade_tool.h => modules/openxr/extensions/openxr_performance_settings_extension.h} (62%) create mode 100644 engine/modules/openxr/openxr_api_extension.compat.inc create mode 100644 engine/platform/android/java/editor/src/main/res/drawable/audio_player.xml create mode 100644 engine/platform/android/java/editor/src/main/res/drawable/audio_player_icon_selector.xml create mode 100644 engine/platform/android/java/editor/src/main/res/drawable/audio_player_muted.xml create mode 100644 engine/platform/ios/platform_thread.h create mode 100644 engine/platform/linuxbsd/freedesktop_at_spi_monitor.cpp rename engine/{modules/openxr/extensions/openxr_composition_layer_provider.h => platform/linuxbsd/freedesktop_at_spi_monitor.h} (78%) create mode 100644 engine/platform/linuxbsd/msvs.py create mode 100644 engine/platform/macos/msvs.py create mode 100644 engine/platform/macos/platform_thread.h create mode 100644 engine/platform/windows/uiautomationcore.arm32.def create mode 100644 engine/platform/windows/uiautomationcore.arm64.def create mode 100644 engine/platform/windows/uiautomationcore.x86_32.def create mode 100644 engine/platform/windows/uiautomationcore.x86_64.def create mode 100644 engine/scene/2d/navigation/SCsub rename engine/scene/2d/{ => navigation}/navigation_agent_2d.cpp (99%) rename engine/scene/2d/{ => navigation}/navigation_agent_2d.h (99%) rename engine/scene/2d/{ => navigation}/navigation_link_2d.cpp (98%) rename engine/scene/2d/{ => navigation}/navigation_link_2d.h (98%) rename engine/scene/2d/{ => navigation}/navigation_obstacle_2d.cpp (99%) rename engine/scene/2d/{ => navigation}/navigation_obstacle_2d.h (97%) rename engine/scene/2d/{ => navigation}/navigation_region_2d.cpp (96%) rename engine/scene/2d/{ => navigation}/navigation_region_2d.h (96%) rename engine/scene/2d/{ => physics}/touch_screen_button.cpp (94%) rename engine/scene/2d/{ => physics}/touch_screen_button.h (97%) create mode 100644 engine/scene/3d/navigation/SCsub rename engine/scene/3d/{ => navigation}/navigation_agent_3d.cpp (99%) rename engine/scene/3d/{ => navigation}/navigation_agent_3d.h (99%) rename engine/scene/3d/{ => navigation}/navigation_link_3d.cpp (99%) rename engine/scene/3d/{ => navigation}/navigation_link_3d.h (97%) rename engine/scene/3d/{ => navigation}/navigation_obstacle_3d.cpp (99%) rename engine/scene/3d/{ => navigation}/navigation_obstacle_3d.h (98%) rename engine/scene/3d/{ => navigation}/navigation_region_3d.cpp (98%) rename engine/scene/3d/{ => navigation}/navigation_region_3d.h (96%) rename engine/scene/3d/{ => physics}/physical_bone_simulator_3d.cpp (97%) rename engine/scene/3d/{ => physics}/physical_bone_simulator_3d.h (96%) rename engine/scene/3d/{ => physics}/soft_body_3d.compat.inc (100%) rename engine/scene/3d/{ => physics}/soft_body_3d.cpp (100%) rename engine/scene/3d/{ => physics}/soft_body_3d.h (99%) create mode 100644 engine/scene/3d/xr/SCsub rename engine/scene/3d/{ => xr}/xr_body_modifier_3d.cpp (99%) rename engine/scene/3d/{ => xr}/xr_body_modifier_3d.h (96%) rename engine/scene/3d/{ => xr}/xr_face_modifier_3d.cpp (99%) rename engine/scene/3d/{ => xr}/xr_face_modifier_3d.h (96%) rename engine/scene/3d/{ => xr}/xr_hand_modifier_3d.cpp (99%) rename engine/scene/3d/{ => xr}/xr_hand_modifier_3d.h (96%) rename engine/scene/3d/{ => xr}/xr_nodes.cpp (90%) rename engine/scene/3d/{ => xr}/xr_nodes.h (97%) create mode 100644 engine/scene/gui/color_picker_shape.cpp create mode 100644 engine/scene/gui/color_picker_shape.h create mode 100644 engine/scene/gui/foldable_container.cpp create mode 100644 engine/scene/gui/foldable_container.h create mode 100644 engine/scene/gui/tree.compat.inc create mode 100644 engine/scene/resources/2d/skeleton/SCsub create mode 100644 engine/scene/theme/icons/arrow_up.svg create mode 100644 engine/servers/display_server.compat.inc create mode 100644 engine/servers/navigation/nav_heap.h create mode 100644 engine/tests/core/io/test_stream_peer_gzip.h create mode 100644 engine/tests/core/math/test_triangle_mesh.h create mode 100644 engine/tests/core/templates/test_span.h create mode 100644 engine/tests/data/exactly_4096_bytes_fastlz.bin delete mode 100644 engine/tests/python_build/conftest.py create mode 100644 engine/tests/python_build/fixtures/gles3/vertex_fragment.out delete mode 100644 engine/tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl delete mode 100644 engine/tests/python_build/fixtures/gles3/vertex_fragment_expected_parts.json rename engine/tests/python_build/fixtures/glsl/{compute_expected_full.glsl => compute.out} (58%) delete mode 100644 engine/tests/python_build/fixtures/glsl/compute_expected_parts.json rename engine/tests/python_build/fixtures/glsl/{vertex_fragment_expected_full.glsl => vertex_fragment.out} (74%) delete mode 100644 engine/tests/python_build/fixtures/glsl/vertex_fragment_expected_parts.json rename engine/tests/python_build/fixtures/rd_glsl/{compute_expected_full.glsl => compute.out} (62%) delete mode 100644 engine/tests/python_build/fixtures/rd_glsl/compute_expected_parts.json rename engine/tests/python_build/fixtures/rd_glsl/{vertex_fragment_expected_full.glsl => vertex_fragment.out} (70%) delete mode 100644 engine/tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_parts.json delete mode 100644 engine/tests/python_build/test_gles3_builder.py delete mode 100644 engine/tests/python_build/test_glsl_builder.py create mode 100644 engine/tests/python_build/validate_builders.py create mode 100644 engine/tests/servers/test_nav_heap.h create mode 100644 engine/thirdparty/accesskit/LICENSE-MIT create mode 100644 engine/thirdparty/accesskit/include/accesskit.h rename engine/thirdparty/clipper2/patches/{0002-llvm-disable-int1280-math.patch => 0002-llvm-disable-int128-math.patch} (74%) create mode 100644 engine/thirdparty/freetype/src/sfnt/ttgpos.c create mode 100644 engine/thirdparty/freetype/src/sfnt/ttgpos.h create mode 100644 engine/thirdparty/harfbuzz/src/hb-decycler.hh delete mode 100644 engine/thirdparty/harfbuzz/src/hb-subset-repacker.h rename engine/thirdparty/harfbuzz/src/{hb-subset-repacker.cc => hb-subset-serialize.cc} (68%) create mode 100644 engine/thirdparty/harfbuzz/src/hb-subset-serialize.h create mode 100644 engine/thirdparty/jolt_physics/Jolt/Physics/Character/CharacterID.h create mode 100644 engine/thirdparty/jolt_physics/Jolt/Physics/Collision/CollideShapeVsShapePerLeaf.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouper.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.cpp delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperMorton.cpp delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleGrouper/TriangleGrouperMorton.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.cpp delete mode 100644 engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.h delete mode 100644 engine/thirdparty/mbedtls/patches/0002-pr-9981-defragment-incoming-tls-handshake-messages.patch delete mode 100644 engine/thirdparty/pcre2/AUTHORS create mode 100644 engine/thirdparty/pcre2/AUTHORS.md rename engine/thirdparty/pcre2/{LICENCE => LICENCE.md} (55%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitExecAllocatorApple.c (98%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitExecAllocatorCore.c (96%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitExecAllocatorFreeBSD.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitExecAllocatorPosix.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitExecAllocatorWindows.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitProtExecAllocatorNetBSD.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitProtExecAllocatorPosix.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitWXExecAllocatorPosix.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/allocator_src/sljitWXExecAllocatorWindows.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitConfig.h (93%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitConfigCPU.h (98%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitConfigInternal.h (82%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitLir.c (77%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitLir.h (83%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeARM_32.c (86%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeARM_64.c (83%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeARM_T2_32.c (86%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeLOONGARCH_64.c (73%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeMIPS_32.c (98%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeMIPS_64.c (98%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeMIPS_common.c (93%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativePPC_32.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativePPC_64.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativePPC_common.c (86%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeRISCV_32.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeRISCV_64.c (100%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeRISCV_common.c (69%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeS390X.c (90%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeX86_32.c (92%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeX86_64.c (89%) rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitNativeX86_common.c (79%) create mode 100644 engine/thirdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c rename engine/thirdparty/pcre2/{src/sljit => deps/sljit/sljit_src}/sljitUtils.c (100%) create mode 100644 engine/thirdparty/pcre2/src/pcre2_compile.h create mode 100644 engine/thirdparty/pcre2/src/pcre2_compile_class.c create mode 100644 engine/thirdparty/pcre2/src/pcre2_jit_char_inc.h create mode 100644 engine/thirdparty/pcre2/src/pcre2_util.h create mode 100644 engine/thirdparty/thorvg/patches/0002-png-explicit-variable-scope.patch rename {engine/modules => modules}/PROJECT/SCsub (100%) rename {engine/modules => modules}/PROJECT/config.py (100%) rename {engine/modules => modules}/PROJECT/macros.h (100%) rename {engine/modules => modules}/PROJECT/register_types.cpp (100%) rename {engine/modules => modules}/PROJECT/register_types.h (100%) diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..1b15f551 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "engine"] + path = engine + url = https://github.com/godotengine/godot.git diff --git a/engine/.clangd b/engine/.clangd index 95a1e907..3c9792ea 100644 --- a/engine/.clangd +++ b/engine/.clangd @@ -5,7 +5,6 @@ Diagnostics: Includes: IgnoreHeader: - - core/typedefs\.h # Our "main" header, featuring transitive includes; allow everywhere. - \.compat\.inc --- # Header-specific conditions. diff --git a/engine/.editorconfig b/engine/.editorconfig index a2f93af3..c79c816e 100644 --- a/engine/.editorconfig +++ b/engine/.editorconfig @@ -16,5 +16,6 @@ indent_style = space indent_size = 2 indent_style = space -[*.svg] -insert_final_newline = false +[{*.props,*.vcxproj}] +indent_size = 2 +indent_style = space diff --git a/engine/.git-blame-ignore-revs b/engine/.git-blame-ignore-revs index d54ff309..3203caf8 100644 --- a/engine/.git-blame-ignore-revs +++ b/engine/.git-blame-ignore-revs @@ -66,3 +66,9 @@ bb5f390fb9b466be35a5df7651323d7e66afca31 # Style: Enforce `AllowShortFunctionsOnASingleLine` e06d83860d798b6766b23d6eae48557387a7db85 + +# Style: Enforce trailing newlines on svgs +7e5baa042639ffa835271703c720e2595e90afb8 + +# Style: Replace header guards with `#pragma once` +324512e11c1b7663c3cf47bec6ddbe65c6b8db2b diff --git a/engine/.gitignore b/engine/.gitignore index 2c3bf742..8adc7b78 100644 --- a/engine/.gitignore +++ b/engine/.gitignore @@ -263,6 +263,11 @@ bld/ !thirdparty/**/arm/ !thirdparty/**/arm64/ +thirdparty/swappy-frame-pacing/arm64-v8a/abi.json +thirdparty/swappy-frame-pacing/armeabi-v7a/abi.json +thirdparty/swappy-frame-pacing/x86/abi.json +thirdparty/swappy-frame-pacing/x86_64/abi.json + # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/engine/.pre-commit-config.yaml b/engine/.pre-commit-config.yaml index 5627d750..8c9f033a 100644 --- a/engine/.pre-commit-config.yaml +++ b/engine/.pre-commit-config.yaml @@ -4,24 +4,22 @@ default_language_version: exclude: | (?x)^( .*thirdparty/.*| - .*-so_wrap\.(h|c)| + .*-(dll|dylib|so)_wrap\.[ch]| platform/android/java/editor/src/main/java/com/android/.*| platform/android/java/lib/src/com/google/.* )$ repos: - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v19.1.3 + rev: v20.1.0 hooks: - id: clang-format files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java)$ types_or: [text] - exclude: ^tests/python_build/.* - id: clang-format name: clang-format-glsl files: \.glsl$ types_or: [text] - exclude: ^tests/python_build/.* args: [-style=file:misc/utility/clang_format_glsl.yml] - repo: https://github.com/pocc/pre-commit-hooks @@ -31,13 +29,12 @@ repos: files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$ args: [--fix, --quiet, --use-color] types_or: [text] - exclude: ^tests/python_build/.* - additional_dependencies: [clang-tidy==19.1.0] + additional_dependencies: [clang-tidy==20.1.0] require_serial: true stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy` - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.4 + rev: v0.11.4 hooks: - id: ruff args: [--fix] @@ -48,14 +45,14 @@ repos: types_or: [text] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.14.1 + rev: v1.14.1 # Latest version that supports Python 3.8 hooks: - id: mypy files: \.py$ types_or: [text] - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.1 hooks: - id: codespell additional_dependencies: [tomli] @@ -88,6 +85,13 @@ repos: pass_filenames: false files: ^(doc/classes|.*/doc_classes)/.*\.xml$ + - id: validate-builders + name: validate-builders + language: python + entry: python tests/python_build/validate_builders.py + pass_filenames: false + files: ^(gles3|glsl)_builders\.py$ + - id: eslint name: eslint language: node @@ -154,7 +158,6 @@ repos: language: python entry: python misc/scripts/header_guards.py files: \.(h|hpp|hh|hxx)$ - exclude: ^.*/(dummy|thread|platform_config|platform_gl)\.h$ - id: file-format name: file-format diff --git a/engine/COPYRIGHT.txt b/engine/COPYRIGHT.txt index 34aa95ed..38009093 100644 --- a/engine/COPYRIGHT.txt +++ b/engine/COPYRIGHT.txt @@ -163,6 +163,11 @@ Comment: Temporal Anti-Aliasing resolve implementation Copyright: 2016, Panos Karabelas License: Expat +Files: thirdparty/accesskit/* +Comment: AccessKit +Copyright: 2023, The AccessKit Authors. +License: Expat + Files: thirdparty/amd-fsr/* Comment: AMD FidelityFX Super Resolution Copyright: 2021, Advanced Micro Devices, Inc. @@ -200,7 +205,7 @@ License: MPL-2.0 Files: thirdparty/clipper2/* Comment: Clipper2 -Copyright: 2010-2024, Angus Johnson +Copyright: 2010-2025, Angus Johnson License: BSL-1.0 Files: thirdparty/cvtt/* diff --git a/engine/SConstruct b/engine/SConstruct index f4500d75..03990864 100644 --- a/engine/SConstruct +++ b/engine/SConstruct @@ -14,6 +14,7 @@ from importlib.util import module_from_spec, spec_from_file_location from types import ModuleType from SCons import __version__ as scons_raw_version +from SCons.Builder import ListEmitter # Explicitly resolve the helper modules, this is done to avoid clash with # modules of the same name that might be randomly added (e.g. someone adding @@ -57,7 +58,7 @@ import gles3_builders import glsl_builders import methods import scu_builders -from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning +from misc.utility.color import is_stderr_color, print_error, print_info, print_warning from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases if ARGUMENTS.get("target", "editor") == "editor": @@ -166,7 +167,7 @@ opts.Add( "optimize", "Optimization level (by default inferred from 'target' and 'dev_build')", "auto", - ("auto", "none", "custom", "debug", "speed", "speed_trace", "size"), + ("auto", "none", "custom", "debug", "speed", "speed_trace", "size", "size_extra"), ) ) opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False)) @@ -186,11 +187,12 @@ opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) opts.Add(BoolVariable("d3d12", "Enable the Direct3D 12 rendering driver on supported platforms", False)) opts.Add(BoolVariable("metal", "Enable the Metal rendering driver on supported platforms (Apple arm64 only)", False)) -opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True)) opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", True)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) +opts.Add(BoolVariable("accesskit", "Use AccessKit C SDK", True)) +opts.Add(("accesskit_sdk_path", "Path to the AccessKit C SDK", "")) # Advanced options opts.Add( @@ -220,6 +222,11 @@ opts.Add("vsproj_name", "Name of the Visual Studio solution", "godot") opts.Add("import_env_vars", "A comma-separated list of environment variables to copy from the outer environment.", "") opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) +opts.Add(BoolVariable("disable_physics_2d", "Disable 2D physics nodes and server", False)) +opts.Add(BoolVariable("disable_physics_3d", "Disable 3D physics nodes and server", False)) +opts.Add(BoolVariable("disable_navigation_2d", "Disable 2D navigation features", False)) +opts.Add(BoolVariable("disable_navigation_3d", "Disable 3D navigation features", False)) +opts.Add(BoolVariable("disable_xr", "Disable XR nodes and server", False)) opts.Add("build_profile", "Path to a file containing a feature build profile", "") opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True)) opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True)) @@ -236,6 +243,13 @@ opts.Add(BoolVariable("engine_update_check", "Enable engine update checks in the opts.Add(BoolVariable("steamapi", "Enable minimal SteamAPI integration for usage time tracking (editor only)", False)) opts.Add("cache_path", "Path to a directory where SCons cache files will be stored. No value disables the cache.", "") opts.Add("cache_limit", "Max size (in GiB) for the SCons cache. 0 means no limit.", "0") +opts.Add( + BoolVariable( + "redirect_build_objects", + "Enable redirecting built objects/libraries to `bin/obj/` to declutter the repository.", + True, + ) +) # Thirdparty libraries opts.Add(BoolVariable("builtin_brotli", "Use the built-in Brotli library", True)) @@ -433,10 +447,19 @@ for tool in custom_tools: env.Tool(tool) -# add default include paths - +# Add default include paths. env.Prepend(CPPPATH=["#"]) +# Allow marking includes as external/system to avoid raising warnings. +env["_CCCOMCOM"] += " $_CPPEXTINCFLAGS" +env["CPPEXTPATH"] = [] +if env.scons_version < (4, 2): + env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}" +else: + env["_CPPEXTINCFLAGS"] = ( + "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}" + ) + # configure ENV for platform env.platform_exporters = platform_exporters env.platform_apis = platform_apis @@ -696,83 +719,84 @@ if env["arch"] == "x86_32": # Explicitly specify colored output. if methods.using_gcc(env): - env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"]) + env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if is_stderr_color() else "-fno-diagnostics-color"]) elif methods.using_clang(env) or methods.using_emcc(env): - env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"]) + env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if is_stderr_color() else "-fno-color-diagnostics"]) if sys.platform == "win32": env.AppendUnique(CCFLAGS=["-fansi-escape-codes"]) # Set optimize and debug_symbols flags. # "custom" means do nothing and let users set their own optimization flags. # Needs to happen after configure to have `env.msvc` defined. +env.AppendUnique(CCFLAGS=["$OPTIMIZELEVEL"]) if env.msvc: if env["debug_symbols"]: - env.Append(CCFLAGS=["/Zi", "/FS"]) - env.Append(LINKFLAGS=["/DEBUG:FULL"]) + env.AppendUnique(CCFLAGS=["/Zi", "/FS"]) + env.AppendUnique(LINKFLAGS=["/DEBUG:FULL"]) else: - env.Append(LINKFLAGS=["/DEBUG:NONE"]) + env.AppendUnique(LINKFLAGS=["/DEBUG:NONE"]) if env["optimize"].startswith("speed"): - env.Append(CCFLAGS=["/O2"]) - env.Append(LINKFLAGS=["/OPT:REF"]) + env["OPTIMIZELEVEL"] = "/O2" + env.AppendUnique(LINKFLAGS=["/OPT:REF"]) if env["optimize"] == "speed_trace": - env.Append(LINKFLAGS=["/OPT:NOICF"]) - elif env["optimize"] == "size": - env.Append(CCFLAGS=["/O1"]) - env.Append(LINKFLAGS=["/OPT:REF"]) + env.AppendUnique(LINKFLAGS=["/OPT:NOICF"]) + elif env["optimize"].startswith("size"): + env["OPTIMIZELEVEL"] = "/O1" + env.AppendUnique(LINKFLAGS=["/OPT:REF"]) + if env["optimize"] == "size_extra": + env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"]) elif env["optimize"] == "debug" or env["optimize"] == "none": - env.Append(CCFLAGS=["/Od"]) + env["OPTIMIZELEVEL"] = "/Od" else: if env["debug_symbols"]: if env["platform"] == "windows": if methods.using_clang(env): - env.Append(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows. + env.AppendUnique(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows. else: - env.Append(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace. + env.AppendUnique(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace. else: # Adding dwarf-4 explicitly makes stacktraces work with clang builds, # otherwise addr2line doesn't understand them - env.Append(CCFLAGS=["-gdwarf-4"]) + env.AppendUnique(CCFLAGS=["-gdwarf-4"]) if methods.using_emcc(env): # Emscripten only produces dwarf symbols when using "-g3". - env.Append(CCFLAGS=["-g3"]) + env.AppendUnique(CCFLAGS=["-g3"]) # Emscripten linker needs debug symbols options too. - env.Append(LINKFLAGS=["-gdwarf-4"]) - env.Append(LINKFLAGS=["-g3"]) + env.AppendUnique(LINKFLAGS=["-gdwarf-4"]) + env.AppendUnique(LINKFLAGS=["-g3"]) elif env.dev_build: - env.Append(CCFLAGS=["-g3"]) + env.AppendUnique(CCFLAGS=["-g3"]) else: - env.Append(CCFLAGS=["-g2"]) + env.AppendUnique(CCFLAGS=["-g2"]) if env["debug_paths_relative"]: # Remap absolute paths to relative paths for debug symbols. project_path = Dir("#").abspath - env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."]) + env.AppendUnique(CCFLAGS=[f"-ffile-prefix-map={project_path}=."]) else: if methods.is_apple_clang(env): # Apple Clang, its linker doesn't like -s. - env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) + env.AppendUnique(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) else: - env.Append(LINKFLAGS=["-s"]) + env.AppendUnique(LINKFLAGS=["-s"]) # Linker needs optimization flags too, at least for Emscripten. # For other toolchains, this _may_ be useful for LTO too to disambiguate. + env.AppendUnique(LINKFLAGS=["$OPTIMIZELEVEL"]) if env["optimize"] == "speed": - env.Append(CCFLAGS=["-O3"]) - env.Append(LINKFLAGS=["-O3"]) + env["OPTIMIZELEVEL"] = "-O3" # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces. elif env["optimize"] == "speed_trace": - env.Append(CCFLAGS=["-O2"]) - env.Append(LINKFLAGS=["-O2"]) - elif env["optimize"] == "size": - env.Append(CCFLAGS=["-Os"]) - env.Append(LINKFLAGS=["-Os"]) + env["OPTIMIZELEVEL"] = "-O2" + elif env["optimize"].startswith("size"): + env["OPTIMIZELEVEL"] = "-Os" + if env["optimize"] == "size_extra": + env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"]) elif env["optimize"] == "debug": - env.Append(CCFLAGS=["-Og"]) - env.Append(LINKFLAGS=["-Og"]) + env["OPTIMIZELEVEL"] = "-Og" elif env["optimize"] == "none": - env.Append(CCFLAGS=["-O0"]) - env.Append(LINKFLAGS=["-O0"]) + env["OPTIMIZELEVEL"] = "-O0" # Needs to happen after configure to handle "auto". if env["lto"] != "none": @@ -813,6 +837,7 @@ elif env.msvc: env.Append(CXXFLAGS=["/EHsc"]) # Configure compiler warnings +env.AppendUnique(CCFLAGS=["$WARNLEVEL"]) if env.msvc and not methods.using_clang(env): # MSVC # Disable warnings which we don't plan to fix. disabled_warnings = [ @@ -830,19 +855,23 @@ if env.msvc and not methods.using_clang(env): # MSVC ] if env["warnings"] == "extra": - env.Append(CCFLAGS=["/W4"] + disabled_warnings) + env["WARNLEVEL"] = "/W4" + env.AppendUnique(CCFLAGS=disabled_warnings) elif env["warnings"] == "all": + env["WARNLEVEL"] = "/W3" # C4458 is like -Wshadow. Part of /W4 but let's apply it for the default /W3 too. - env.Append(CCFLAGS=["/W3", "/w34458"] + disabled_warnings) + env.AppendUnique(CCFLAGS=["/w34458"] + disabled_warnings) elif env["warnings"] == "moderate": - env.Append(CCFLAGS=["/W2"] + disabled_warnings) + env["WARNLEVEL"] = "/W2" + env.AppendUnique(CCFLAGS=disabled_warnings) else: # 'no' + env["WARNLEVEL"] = "/w" # C4267 is particularly finicky & needs to be explicitly disabled. - env.Append(CCFLAGS=["/w", "/wd4267"]) + env.AppendUnique(CCFLAGS=["/wd4267"]) if env["werror"]: - env.Append(CCFLAGS=["/WX"]) - env.Append(LINKFLAGS=["/WX"]) + env.AppendUnique(CCFLAGS=["/WX"]) + env.AppendUnique(LINKFLAGS=["/WX"]) else: # GCC, Clang common_warnings = [] @@ -861,14 +890,14 @@ else: # GCC, Clang # for putting them in `Set` or `Map`. We don't mind about unreliable ordering. common_warnings += ["-Wno-ordered-compare-function-pointers"] - # clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast - W_ALL = "-Wall" if not env.msvc else "-W3" + # clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast. + env["WARNLEVEL"] = "-Wall" if not env.msvc else "-W3" if env["warnings"] == "extra": - env.Append(CCFLAGS=[W_ALL, "-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings) - env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"]) + env.AppendUnique(CCFLAGS=["-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings) + env.AppendUnique(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"]) if methods.using_gcc(env): - env.Append( + env.AppendUnique( CCFLAGS=[ "-Walloc-zero", "-Wduplicated-branches", @@ -876,25 +905,38 @@ else: # GCC, Clang "-Wstringop-overflow=4", ] ) - env.Append(CXXFLAGS=["-Wplacement-new=1"]) + env.AppendUnique(CXXFLAGS=["-Wplacement-new=1", "-Wvirtual-inheritance"]) # Need to fix a warning with AudioServer lambdas before enabling. # if cc_version_major != 9: # GCC 9 had a regression (GH-36325). # env.Append(CXXFLAGS=["-Wnoexcept"]) if cc_version_major >= 9: - env.Append(CCFLAGS=["-Wattribute-alias=2"]) + env.AppendUnique(CCFLAGS=["-Wattribute-alias=2"]) if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11. - env.Append(CCFLAGS=["-Wlogical-op"]) + env.AppendUnique(CCFLAGS=["-Wlogical-op"]) elif methods.using_clang(env) or methods.using_emcc(env): - env.Append(CCFLAGS=["-Wimplicit-fallthrough"]) + env.AppendUnique(CCFLAGS=["-Wimplicit-fallthrough"]) elif env["warnings"] == "all": - env.Append(CCFLAGS=[W_ALL] + common_warnings) + env.AppendUnique(CCFLAGS=common_warnings) elif env["warnings"] == "moderate": - env.Append(CCFLAGS=[W_ALL, "-Wno-unused"] + common_warnings) + env.AppendUnique(CCFLAGS=["-Wno-unused"] + common_warnings) else: # 'no' - env.Append(CCFLAGS=["-w"]) + env["WARNLEVEL"] = "-w" if env["werror"]: - env.Append(CCFLAGS=["-Werror"]) + env.AppendUnique(CCFLAGS=["-Werror"]) + +# Configure external includes. +if env.msvc: + if not methods.using_clang(env): + if cc_version_major < 16 or (cc_version_major == 16 and cc_version_minor < 10): + env.AppendUnique(CCFLAGS=["/experimental:external"]) + env.AppendUnique(CCFLAGS=["/external:anglebrackets"]) + env.AppendUnique(CCFLAGS=["/external:W0"]) + env["EXTINCPREFIX"] = "/external:I" + env["EXTINCSUFFIX"] = "" +else: + env["EXTINCPREFIX"] = "-isystem " + env["EXTINCSUFFIX"] = "" if hasattr(detect, "get_program_suffix"): suffix = "." + detect.get_program_suffix() @@ -918,6 +960,51 @@ suffix += env.extra_suffix sys.path.remove(tmppath) sys.modules.pop("detect") +if env.editor_build: + unsupported_opts = [] + for disable_opt in [ + "disable_3d", + "disable_advanced_gui", + "disable_physics_2d", + "disable_physics_3d", + "disable_navigation_2d", + "disable_navigation_3d", + ]: + if env[disable_opt]: + unsupported_opts.append(disable_opt) + if unsupported_opts != []: + print_error( + "The following build option(s) cannot be used for editor builds, but only for export template builds: {}.".format( + ", ".join(unsupported_opts) + ) + ) + Exit(255) + +if env["disable_3d"]: + env.Append(CPPDEFINES=["_3D_DISABLED"]) + env["disable_navigation_3d"] = True + env["disable_physics_3d"] = True + env["disable_xr"] = True +if env["disable_advanced_gui"]: + env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) +if env["disable_physics_2d"]: + env.Append(CPPDEFINES=["PHYSICS_2D_DISABLED"]) +if env["disable_physics_3d"]: + env.Append(CPPDEFINES=["PHYSICS_3D_DISABLED"]) +if env["disable_navigation_2d"]: + env.Append(CPPDEFINES=["NAVIGATION_2D_DISABLED"]) +if env["disable_navigation_3d"]: + env.Append(CPPDEFINES=["NAVIGATION_3D_DISABLED"]) +if env["disable_xr"]: + env.Append(CPPDEFINES=["XR_DISABLED"]) +if env["minizip"]: + env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) +if env["brotli"]: + env.Append(CPPDEFINES=["BROTLI_ENABLED"]) + +if not env["verbose"]: + methods.no_verbose(env) + modules_enabled = OrderedDict() env.module_dependencies = {} env.module_icons_paths = [] @@ -968,8 +1055,6 @@ if env.editor_build: print_error("Not all modules required by editor builds are enabled.") Exit(255) -env.version_info = methods.get_version_info(env.module_version_string) - env["PROGSUFFIX_WRAP"] = suffix + env.module_version_string + ".console" + env["PROGSUFFIX"] env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"] env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"] @@ -989,28 +1074,6 @@ env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"] env["OBJPREFIX"] = env["object_prefix"] env["SHOBJPREFIX"] = env["object_prefix"] -if env["disable_3d"]: - if env.editor_build: - print_error("Build option `disable_3d=yes` cannot be used for editor builds, only for export template builds.") - Exit(255) - else: - env.Append(CPPDEFINES=["_3D_DISABLED"]) -if env["disable_advanced_gui"]: - if env.editor_build: - print_error( - "Build option `disable_advanced_gui=yes` cannot be used for editor builds, only for export template builds." - ) - Exit(255) - else: - env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"]) -if env["minizip"]: - env.Append(CPPDEFINES=["MINIZIP_ENABLED"]) -if env["brotli"]: - env.Append(CPPDEFINES=["BROTLI_ENABLED"]) - -if not env["verbose"]: - methods.no_verbose(env) - GLSL_BUILDERS = { "RD_GLSL": env.Builder( action=env.Run(glsl_builders.build_rd_headers), @@ -1051,6 +1114,14 @@ if env["ninja"]: if env["threads"]: env.Append(CPPDEFINES=["THREADS_ENABLED"]) +# Ensure build objects are put in their own folder if `redirect_build_objects` is enabled. +env.Prepend(LIBEMITTER=[methods.redirect_emitter]) +env.Prepend(SHLIBEMITTER=[methods.redirect_emitter]) +for key in (emitters := env.StaticObject.builder.emitter): + emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key])) +for key in (emitters := env.SharedObject.builder.emitter): + emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key])) + # Build subdirs, the build order is dependent on link order. Export("env") @@ -1082,11 +1153,11 @@ if "check_c_headers" in env: for header in headers: if conf.CheckCHeader(header): env.AppendUnique(CPPDEFINES=[headers[header]]) +conf.Finish() - -methods.show_progress(env) -# TODO: replace this with `env.Dump(format="json")` -# once we start requiring SCons 4.0 as min version. -methods.dump(env) -methods.prepare_purge(env) -methods.prepare_timer() +# Miscellaneous & post-build methods. +if not env.GetOption("clean") and not env.GetOption("help"): + methods.dump(env) + methods.show_progress(env) + methods.prepare_purge(env) + methods.prepare_timer() diff --git a/engine/core/SCsub b/engine/core/SCsub index f055a75c..a252a074 100644 --- a/engine/core/SCsub +++ b/engine/core/SCsub @@ -51,8 +51,8 @@ if env["brotli"] and env["builtin_brotli"]: ] thirdparty_brotli_sources = [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) - env.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) + env.Prepend(CPPEXTPATH=[thirdparty_brotli_dir + "include"]) if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"): env_thirdparty.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"]) @@ -69,8 +69,8 @@ if env["builtin_clipper2"]: ] thirdparty_clipper_sources = [thirdparty_clipper_dir + file for file in thirdparty_clipper_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) - env.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) + env.Prepend(CPPEXTPATH=[thirdparty_clipper_dir + "include"]) env_thirdparty.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) env.Append(CPPDEFINES=["CLIPPER2_ENABLED"]) @@ -94,9 +94,9 @@ if env["builtin_zlib"]: ] thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) # Needs to be available in main env too - env.Prepend(CPPPATH=[thirdparty_zlib_dir]) + env.Prepend(CPPEXTPATH=[thirdparty_zlib_dir]) if env.dev_build: env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"]) # Affects headers so it should also be defined for Godot code @@ -148,9 +148,9 @@ if env["builtin_zstd"]: thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S") thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] - env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) + env_thirdparty.Prepend(CPPEXTPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) - env.Prepend(CPPPATH=thirdparty_zstd_dir) + env.Prepend(CPPEXTPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) @@ -167,10 +167,9 @@ env.add_source_files(env.core_sources, "*.cpp") # Generate disabled classes def disabled_class_builder(target, source, env): - with methods.generated_wrapper(target) as file: + with methods.generated_wrapper(str(target[0])) as file: for c in source[0].read(): - cs = c.strip() - if cs != "": + if cs := c.strip(): file.write(f"#define ClassDB_Disable_{cs} 1\n") @@ -179,49 +178,51 @@ env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), en # Generate version info def version_info_builder(target, source, env): - with methods.generated_wrapper(target) as file: + with methods.generated_wrapper(str(target[0])) as file: file.write( """\ -#define VERSION_SHORT_NAME "{short_name}" -#define VERSION_NAME "{name}" -#define VERSION_MAJOR {major} -#define VERSION_MINOR {minor} -#define VERSION_PATCH {patch} -#define VERSION_STATUS "{status}" -#define VERSION_BUILD "{build}" -#define VERSION_MODULE_CONFIG "{module_config}" -#define VERSION_WEBSITE "{website}" -#define VERSION_DOCS_BRANCH "{docs_branch}" -#define VERSION_DOCS_URL "https://docs.godotengine.org/en/" VERSION_DOCS_BRANCH -""".format(**env.version_info) +#define GODOT_VERSION_SHORT_NAME "{short_name}" +#define GODOT_VERSION_NAME "{name}" +#define GODOT_VERSION_MAJOR {major} +#define GODOT_VERSION_MINOR {minor} +#define GODOT_VERSION_PATCH {patch} +#define GODOT_VERSION_STATUS "{status}" +#define GODOT_VERSION_BUILD "{build}" +#define GODOT_VERSION_MODULE_CONFIG "{module_config}" +#define GODOT_VERSION_WEBSITE "{website}" +#define GODOT_VERSION_DOCS_BRANCH "{docs_branch}" +#define GODOT_VERSION_DOCS_URL "https://docs.godotengine.org/en/" GODOT_VERSION_DOCS_BRANCH +""".format(**source[0].read()) ) -env.CommandNoCache("version_generated.gen.h", env.Value(env.version_info), env.Run(version_info_builder)) +env.CommandNoCache( + "version_generated.gen.h", + env.Value(methods.get_version_info(env.module_version_string)), + env.Run(version_info_builder), +) # Generate version hash def version_hash_builder(target, source, env): - with methods.generated_wrapper(target) as file: + with methods.generated_wrapper(str(target[0])) as file: file.write( """\ #include "core/version.h" -const char *const VERSION_HASH = "{git_hash}"; -const uint64_t VERSION_TIMESTAMP = {git_timestamp}; -""".format(**env.version_info) +const char *const GODOT_VERSION_HASH = "{git_hash}"; +const uint64_t GODOT_VERSION_TIMESTAMP = {git_timestamp}; +""".format(**source[0].read()) ) -gen_hash = env.CommandNoCache( - "version_hash.gen.cpp", env.Value(env.version_info["git_hash"]), env.Run(version_hash_builder) -) +gen_hash = env.CommandNoCache("version_hash.gen.cpp", env.Value(methods.get_git_info()), env.Run(version_hash_builder)) env.add_source_files(env.core_sources, gen_hash) # Generate AES256 script encryption key def encryption_key_builder(target, source, env): - with methods.generated_wrapper(target) as file: + with methods.generated_wrapper(str(target[0])) as file: file.write( f"""\ #include "core/config/project_settings.h" @@ -251,30 +252,21 @@ env.add_source_files(env.core_sources, gen_encrypt) # Certificates -env.Depends( - "#core/io/certs_compressed.gen.h", - ["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])], -) env.CommandNoCache( "#core/io/certs_compressed.gen.h", - "#thirdparty/certs/ca-certificates.crt", + ["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])], env.Run(core_builders.make_certs_header), ) # Authors -env.Depends("#core/authors.gen.h", "../AUTHORS.md") -env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header)) +env.CommandNoCache("#core/authors.gen.h", "#AUTHORS.md", env.Run(core_builders.make_authors_header)) # Donors -env.Depends("#core/donors.gen.h", "../DONORS.md") -env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header)) +env.CommandNoCache("#core/donors.gen.h", "#DONORS.md", env.Run(core_builders.make_donors_header)) # License -env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"]) env.CommandNoCache( - "#core/license.gen.h", - ["../COPYRIGHT.txt", "../LICENSE.txt"], - env.Run(core_builders.make_license_header), + "#core/license.gen.h", ["#COPYRIGHT.txt", "#LICENSE.txt"], env.Run(core_builders.make_license_header) ) # Chain load SCsubs diff --git a/engine/core/config/engine.cpp b/engine/core/config/engine.cpp index 402e6281..0f7ead2f 100644 --- a/engine/core/config/engine.cpp +++ b/engine/core/config/engine.cpp @@ -125,17 +125,17 @@ double Engine::get_unfrozen_time_scale() const { Dictionary Engine::get_version_info() const { Dictionary dict; - dict["major"] = VERSION_MAJOR; - dict["minor"] = VERSION_MINOR; - dict["patch"] = VERSION_PATCH; - dict["hex"] = VERSION_HEX; - dict["status"] = VERSION_STATUS; - dict["build"] = VERSION_BUILD; + dict["major"] = GODOT_VERSION_MAJOR; + dict["minor"] = GODOT_VERSION_MINOR; + dict["patch"] = GODOT_VERSION_PATCH; + dict["hex"] = GODOT_VERSION_HEX; + dict["status"] = GODOT_VERSION_STATUS; + dict["build"] = GODOT_VERSION_BUILD; - String hash = String(VERSION_HASH); + String hash = String(GODOT_VERSION_HASH); dict["hash"] = hash.is_empty() ? String("unknown") : hash; - dict["timestamp"] = VERSION_TIMESTAMP; + dict["timestamp"] = GODOT_VERSION_TIMESTAMP; String stringver = String(dict["major"]) + "." + String(dict["minor"]); if ((int)dict["patch"] != 0) { diff --git a/engine/core/config/engine.h b/engine/core/config/engine.h index ec5fb955..701cfda5 100644 --- a/engine/core/config/engine.h +++ b/engine/core/config/engine.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ENGINE_H -#define ENGINE_H +#pragma once #include "core/os/main_loop.h" #include "core/string/ustring.h" @@ -214,5 +213,3 @@ public: Engine(); virtual ~Engine(); }; - -#endif // ENGINE_H diff --git a/engine/core/config/project_settings.cpp b/engine/core/config/project_settings.cpp index e4cc0f9c..565a9734 100644 --- a/engine/core/config/project_settings.cpp +++ b/engine/core/config/project_settings.cpp @@ -77,7 +77,7 @@ String ProjectSettings::get_imported_files_path() const { // This is used by the project manager to provide the initial_settings for config/features. const PackedStringArray ProjectSettings::get_required_features() { PackedStringArray features; - features.append(VERSION_BRANCH); + features.append(GODOT_VERSION_BRANCH); #ifdef REAL_T_IS_DOUBLE features.append("Double Precision"); #endif @@ -92,9 +92,9 @@ const PackedStringArray ProjectSettings::_get_supported_features() { #endif // Allow pinning to a specific patch number or build type by marking // them as supported. They're only used if the user adds them manually. - features.append(VERSION_BRANCH "." _MKSTR(VERSION_PATCH)); - features.append(VERSION_FULL_CONFIG); - features.append(VERSION_FULL_BUILD); + features.append(GODOT_VERSION_BRANCH "." _MKSTR(GODOT_VERSION_PATCH)); + features.append(GODOT_VERSION_FULL_CONFIG); + features.append(GODOT_VERSION_FULL_BUILD); #ifdef RD_ENABLED features.append("Forward Plus"); @@ -173,7 +173,7 @@ String ProjectSettings::localize_path(const String &p_path) const { if (dir->change_dir(path) == OK) { String cwd = dir->get_current_dir(); - cwd = cwd.replace("\\", "/"); + cwd = cwd.replace_char('\\', '/'); // Ensure that we end with a '/'. // This is important to ensure that we do not wrongly localize the resource path @@ -208,7 +208,7 @@ String ProjectSettings::localize_path(const String &p_path) const { if (plocal[plocal.length() - 1] == '/') { sep += 1; } - return plocal + path.substr(sep, path.size() - sep); + return plocal + path.substr(sep); } } @@ -289,7 +289,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { remove_autoload(node_name); } } else if (p_name.operator String().begins_with("global_group/")) { - String group_name = p_name.operator String().get_slice("/", 1); + String group_name = p_name.operator String().get_slicec('/', 1); if (global_groups.has(group_name)) { remove_global_group(group_name); } @@ -340,7 +340,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { } add_autoload(autoload); } else if (p_name.operator String().begins_with("global_group/")) { - String group_name = p_name.operator String().get_slice("/", 1); + String group_name = p_name.operator String().get_slicec('/', 1); add_global_group(group_name, p_value); } } @@ -359,14 +359,14 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { return true; } -Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const { +Variant ProjectSettings::get_setting_with_override_and_custom_features(const StringName &p_name, const Vector &p_features) const { _THREAD_SAFE_METHOD_ StringName name = p_name; if (feature_overrides.has(name)) { const LocalVector> &overrides = feature_overrides[name]; for (uint32_t i = 0; i < overrides.size(); i++) { - if (OS::get_singleton()->has_feature(overrides[i].first)) { // Custom features are checked in OS.has_feature() already. No need to check twice. + if (p_features.has(String(overrides[i].first).to_lower())) { if (props.has(overrides[i].second)) { name = overrides[i].second; break; @@ -376,12 +376,39 @@ Variant ProjectSettings::get_setting_with_override(const StringName &p_name) con } if (!props.has(name)) { - WARN_PRINT(vformat("Property not found: '%s'.", String(name))); + WARN_PRINT("Property not found: " + String(name)); return Variant(); } return props[name].variant; } +Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const { + _THREAD_SAFE_METHOD_ + + const LocalVector> *overrides = feature_overrides.getptr(p_name); + if (overrides) { + for (uint32_t i = 0; i < overrides->size(); i++) { + if (!OS::get_singleton()->has_feature((*overrides)[i].first)) { + continue; + } + + // Custom features are checked in OS.has_feature() already. No need to check twice. + const RBMap::Element *override_prop = props.find((*overrides)[i].second); + if (override_prop) { + return override_prop->get().variant; + } + } + } + + const RBMap::Element *prop = props.find(p_name); + if (!prop) { + WARN_PRINT(vformat("Property not found: '%s'.", p_name)); + return Variant(); + } + + return prop->get().variant; +} + struct _VCSort { String name; Variant::Type type = Variant::VARIANT_MAX; @@ -564,7 +591,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b if (!OS::get_singleton()->get_resource_dir().is_empty()) { // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! // If the OS would rather use a specific location, then it will not be empty. - resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); + resource_path = OS::get_singleton()->get_resource_dir().replace_char('\\', '/'); if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') { resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end. } @@ -685,7 +712,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b while (true) { // Set the resource path early so things can be resolved when loading. resource_path = current_dir; - resource_path = resource_path.replace("\\", "/"); // Windows path to Unix path just in case. + resource_path = resource_path.replace_char('\\', '/'); // Windows path to Unix path just in case. err = _load_settings_text_or_binary(current_dir.path_join("project.godot"), current_dir.path_join("project.binary")); if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. @@ -770,8 +797,7 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) { cs.resize(slen + 1); cs[slen] = 0; f->get_buffer((uint8_t *)cs.ptr(), slen); - String key; - key.parse_utf8(cs.ptr(), slen); + String key = String::utf8(cs.ptr(), slen); uint32_t vlen = f->get_32(); Vector d; @@ -1129,7 +1155,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust category = ""; } else { category = category.substr(0, div); - name = name.substr(div + 1, name.size()); + name = name.substr(div + 1); } save_props[category].push_back(name); } @@ -1141,7 +1167,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust save_features += ","; } - String f = p_custom_features[i].strip_edges().replace("\"", ""); + String f = p_custom_features[i].strip_edges().remove_char('\"'); save_features += f; } @@ -1408,6 +1434,7 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("get_setting", "name", "default_value"), &ProjectSettings::get_setting, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("get_setting_with_override", "name"), &ProjectSettings::get_setting_with_override); ClassDB::bind_method(D_METHOD("get_global_class_list"), &ProjectSettings::get_global_class_list); + ClassDB::bind_method(D_METHOD("get_setting_with_override_and_custom_features", "name", "features"), &ProjectSettings::get_setting_with_override_and_custom_features); ClassDB::bind_method(D_METHOD("set_order", "name", "position"), &ProjectSettings::set_order); ClassDB::bind_method(D_METHOD("get_order", "name"), &ProjectSettings::get_order); ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &ProjectSettings::set_initial_value); @@ -1434,8 +1461,8 @@ void ProjectSettings::_add_builtin_input_map() { Array events; // Convert list of input events into array - for (List>::Element *I = E.value.front(); I; I = I->next()) { - events.push_back(I->get()); + for (const Ref &event : E.value) { + events.push_back(event); } Dictionary action; @@ -1488,6 +1515,9 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("application/config/auto_accept_quit", true); GLOBAL_DEF("application/config/quit_on_go_back", true); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "accessibility/general/accessibility_support", PROPERTY_HINT_ENUM, "Auto (When Screen Reader is Running),Always Active,Disabled"), 0); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "accessibility/general/updates_per_second", PROPERTY_HINT_RANGE, "1,100,1"), 60); + // The default window size is tuned to: // - Have a 16:9 aspect ratio, // - Have both dimensions divisible by 8 to better play along with video recording, @@ -1497,9 +1527,10 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen,Exclusive Fullscreen"), 0); - // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum. - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_position_type", PROPERTY_HINT_ENUM, "Absolute,Center of Primary Screen,Center of Other Screen,Center of Screen With Mouse Pointer,Center of Screen With Keyboard Focus"), 1); + // Keep the enum values in sync with the `Window::WINDOW_INITIAL_POSITION_` enum. + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_position_type", PROPERTY_HINT_ENUM, "Absolute:0,Center of Primary Screen:1,Center of Other Screen:3,Center of Screen With Mouse Pointer:4,Center of Screen With Keyboard Focus:5"), 1); GLOBAL_DEF_BASIC(PropertyInfo(Variant::VECTOR2I, "display/window/size/initial_position"), Vector2i()); + // Keep the enum values in sync with the `DisplayServer::SCREEN_` enum. GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/initial_screen", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), 0); GLOBAL_DEF_BASIC("display/window/size/resizable", true); @@ -1509,6 +1540,8 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/size/extend_to_title", false); GLOBAL_DEF("display/window/size/no_focus", false); GLOBAL_DEF("display/window/size/sharp_corners", false); + GLOBAL_DEF("display/window/size/minimize_disabled", false); + GLOBAL_DEF("display/window/size/maximize_disabled", false); GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution @@ -1543,8 +1576,13 @@ ProjectSettings::ProjectSettings() { #else custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Unsafe (deprecated),Safe,Separate"); #endif + +#ifndef PHYSICS_2D_DISABLED GLOBAL_DEF("physics/2d/run_on_separate_thread", false); +#endif // PHYSICS_2D_DISABLED +#ifndef PHYSICS_3D_DISABLED GLOBAL_DEF("physics/3d/run_on_separate_thread", false); +#endif // PHYSICS_3D_DISABLED GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,canvas_items,viewport"), "disabled"); GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand"), "keep"); @@ -1612,6 +1650,8 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1); + GLOBAL_DEF("input_devices/pointing/android/override_volume_buttons", false); + GLOBAL_DEF_BASIC("input_devices/pointing/android/disable_scroll_deadzone", false); // These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix(). GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray()); @@ -1620,6 +1660,19 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_INTERNAL("internationalization/locale/translations_pot_files", PackedStringArray()); GLOBAL_DEF_INTERNAL("internationalization/locale/translation_add_builtin_strings_to_pot", false); +#if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) + GLOBAL_DEF("navigation/world/map_use_async_iterations", true); + + GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_multiple_threads", true); + GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_high_priority_threads", true); + + GLOBAL_DEF("navigation/pathfinding/max_threads", 4); + + GLOBAL_DEF("navigation/baking/use_crash_prevention_checks", true); + GLOBAL_DEF("navigation/baking/thread_model/baking_use_multiple_threads", true); + GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads", true); +#endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) + ProjectSettings::get_singleton()->add_hidden_prefix("input/"); } diff --git a/engine/core/config/project_settings.h b/engine/core/config/project_settings.h index 02049290..65fa72ea 100644 --- a/engine/core/config/project_settings.h +++ b/engine/core/config/project_settings.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PROJECT_SETTINGS_H -#define PROJECT_SETTINGS_H +#pragma once #include "core/object/class_db.h" @@ -194,6 +193,7 @@ public: List get_input_presets() const { return input_presets; } Variant get_setting_with_override(const StringName &p_name) const; + Variant get_setting_with_override_and_custom_features(const StringName &p_name, const Vector &p_features) const; bool is_using_datapack() const; bool is_project_loaded() const; @@ -243,5 +243,3 @@ Variant _GLOBAL_DEF(const PropertyInfo &p_info, const Variant &p_default, bool p #define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true) #define GLOBAL_DEF_INTERNAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, false, true) - -#endif // PROJECT_SETTINGS_H diff --git a/engine/core/core_bind.compat.inc b/engine/core/core_bind.compat.inc index 22c78623..8bfa66e4 100644 --- a/engine/core/core_bind.compat.inc +++ b/engine/core/core_bind.compat.inc @@ -30,7 +30,7 @@ #ifndef DISABLE_DEPRECATED -namespace core_bind { +namespace CoreBind { // Semaphore @@ -53,10 +53,12 @@ Dictionary OS::_execute_with_pipe_bind_compat_94434(const String &p_path, const } void OS::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin); + ClassDB::bind_compatibility_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin); ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin"), &OS::_read_string_from_stdin_bind_compat_91201); ClassDB::bind_compatibility_method(D_METHOD("execute_with_pipe", "path", "arguments"), &OS::_execute_with_pipe_bind_compat_94434); } -} // namespace core_bind +} // namespace CoreBind #endif // DISABLE_DEPRECATED diff --git a/engine/core/core_bind.cpp b/engine/core/core_bind.cpp index acd58978..d55305b2 100644 --- a/engine/core/core_bind.cpp +++ b/engine/core/core_bind.cpp @@ -42,7 +42,7 @@ #include "core/os/thread_safe.h" #include "core/variant/typed_array.h" -namespace core_bind { +namespace CoreBind { ////// ResourceLoader ////// @@ -466,8 +466,8 @@ bool OS::is_restart_on_exit_set() const { Vector OS::get_restart_on_exit_arguments() const { List args = ::OS::get_singleton()->get_restart_on_exit_arguments(); Vector args_vector; - for (List::Element *E = args.front(); E; E = E->next()) { - args_vector.push_back(E->get()); + for (const String &arg : args) { + args_vector.push_back(arg); } return args_vector; @@ -657,8 +657,8 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_system_font_path_for_text", "font_name", "text", "locale", "script", "weight", "stretch", "italic"), &OS::get_system_font_path_for_text, DEFVAL(String()), DEFVAL(String()), DEFVAL(400), DEFVAL(100), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); - ClassDB::bind_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin); - ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin); + ClassDB::bind_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin, DEFVAL(1024)); + ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin, DEFVAL(1024)); ClassDB::bind_method(D_METHOD("get_stdin_type"), &OS::get_stdin_type); ClassDB::bind_method(D_METHOD("get_stdout_type"), &OS::get_stdout_type); ClassDB::bind_method(D_METHOD("get_stderr_type"), &OS::get_stderr_type); @@ -806,13 +806,11 @@ Vector Geometry2D::get_closest_points_between_segments(const Vector2 &p } Vector2 Geometry2D::get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - Vector2 s[2] = { p_a, p_b }; - return ::Geometry2D::get_closest_point_to_segment(p_point, s); + return ::Geometry2D::get_closest_point_to_segment(p_point, p_a, p_b); } Vector2 Geometry2D::get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) { - Vector2 s[2] = { p_a, p_b }; - return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry2D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); } bool Geometry2D::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const { @@ -1069,13 +1067,11 @@ Vector Geometry3D::get_closest_points_between_segments(const Vector3 &p } Vector3 Geometry3D::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - Vector3 s[2] = { p_a, p_b }; - return ::Geometry3D::get_closest_point_to_segment(p_point, s); + return ::Geometry3D::get_closest_point_to_segment(p_point, p_a, p_b); } Vector3 Geometry3D::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) { - Vector3 s[2] = { p_a, p_b }; - return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, s); + return ::Geometry3D::get_closest_point_to_segment_uncapped(p_point, p_a, p_b); } Vector3 Geometry3D::get_triangle_barycentric_coords(const Vector3 &p_point, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) { @@ -1241,6 +1237,9 @@ Vector Marshalls::base64_to_raw(const String &p_str) { } String Marshalls::utf8_to_base64(const String &p_str) { + if (p_str.is_empty()) { + return String(); + } CharString cstr = p_str.utf8(); String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length()); ERR_FAIL_COND_V(ret.is_empty(), ret); @@ -1340,6 +1339,7 @@ void Thread::_start_func(void *ud) { // When the call returns, we will reference the thread again if possible. ObjectID th_instance_id = t->get_instance_id(); Callable target_callable = t->target_callable; + String id = t->get_id(); t = Ref(); Callable::CallError ce; @@ -1347,7 +1347,7 @@ void Thread::_start_func(void *ud) { target_callable.callp(nullptr, 0, ret, ce); // If script properly kept a reference to the thread, we should be able to re-reference it now // (well, or if the call failed, since we had to break chains anyway because the outcome isn't known upfront). - t = Ref(ObjectDB::get_instance(th_instance_id)); + t = ObjectDB::get_ref(th_instance_id); if (t.is_valid()) { t->ret = ret; t->running.clear(); @@ -1357,7 +1357,7 @@ void Thread::_start_func(void *ud) { } if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_MSG(vformat("Could not call function '%s' to start thread %d: %s.", func_name, t->get_id(), Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce))); + ERR_FAIL_MSG(vformat("Could not call function '%s' to start thread %s: %s.", func_name, id, Variant::get_callable_error_text(target_callable, nullptr, 0, ce))); } } @@ -1419,7 +1419,7 @@ void Thread::_bind_methods() { BIND_ENUM_CONSTANT(PRIORITY_HIGH); } -namespace special { +namespace Special { ////// ClassDB ////// @@ -1438,8 +1438,8 @@ PackedStringArray ClassDB::get_class_list() const { } PackedStringArray ClassDB::get_inheriters_from_class(const StringName &p_class) const { - List classes; - ::ClassDB::get_inheriters_from_class(p_class, &classes); + LocalVector classes; + ::ClassDB::get_inheriters_from_class(p_class, classes); PackedStringArray ret; ret.resize(classes.size()); @@ -1746,7 +1746,7 @@ void ClassDB::_bind_methods() { BIND_ENUM_CONSTANT(API_NONE); } -} // namespace special +} // namespace Special ////// Engine ////// @@ -1876,8 +1876,8 @@ Vector Engine::get_singleton_list() const { List<::Engine::Singleton> singletons; ::Engine::get_singleton()->get_singletons(&singletons); Vector ret; - for (List<::Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - ret.push_back(E->get().name); + for (const ::Engine::Singleton &E : singletons) { + ret.push_back(E.name); } return ret; } @@ -2190,4 +2190,4 @@ void EngineDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_breakpoints"), &EngineDebugger::clear_breakpoints); } -} // namespace core_bind +} // namespace CoreBind diff --git a/engine/core/core_bind.h b/engine/core/core_bind.h index b96dc56b..ec74c53d 100644 --- a/engine/core/core_bind.h +++ b/engine/core/core_bind.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CORE_BIND_H -#define CORE_BIND_H +#pragma once #include "core/debugger/engine_profiler.h" #include "core/io/resource_loader.h" @@ -42,7 +41,7 @@ class MainLoop; template class TypedArray; -namespace core_bind { +namespace CoreBind { class ResourceLoader : public Object { GDCLASS(ResourceLoader, Object); @@ -458,7 +457,7 @@ public: static void set_thread_safety_checks_enabled(bool p_enabled); }; -namespace special { +namespace Special { class ClassDB : public Object { GDCLASS(ClassDB, Object); @@ -524,7 +523,7 @@ public: ~ClassDB() {} }; -} // namespace special +} // namespace Special class Engine : public Object { GDCLASS(Engine, Object); @@ -652,23 +651,21 @@ public: ~EngineDebugger(); }; -} // namespace core_bind +} // namespace CoreBind -VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus); -VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode); +VARIANT_ENUM_CAST(CoreBind::ResourceLoader::ThreadLoadStatus); +VARIANT_ENUM_CAST(CoreBind::ResourceLoader::CacheMode); -VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags); +VARIANT_BITFIELD_CAST(CoreBind::ResourceSaver::SaverFlags); -VARIANT_ENUM_CAST(core_bind::OS::RenderingDriver); -VARIANT_ENUM_CAST(core_bind::OS::SystemDir); -VARIANT_ENUM_CAST(core_bind::OS::StdHandleType); +VARIANT_ENUM_CAST(CoreBind::OS::RenderingDriver); +VARIANT_ENUM_CAST(CoreBind::OS::SystemDir); +VARIANT_ENUM_CAST(CoreBind::OS::StdHandleType); -VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyBooleanOperation); -VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyJoinType); -VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyEndType); +VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyBooleanOperation); +VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyJoinType); +VARIANT_ENUM_CAST(CoreBind::Geometry2D::PolyEndType); -VARIANT_ENUM_CAST(core_bind::Thread::Priority); +VARIANT_ENUM_CAST(CoreBind::Thread::Priority); -VARIANT_ENUM_CAST(core_bind::special::ClassDB::APIType); - -#endif // CORE_BIND_H +VARIANT_ENUM_CAST(CoreBind::Special::ClassDB::APIType); diff --git a/engine/core/core_builders.py b/engine/core/core_builders.py index d7c0603c..5eaac237 100644 --- a/engine/core/core_builders.py +++ b/engine/core/core_builders.py @@ -1,171 +1,104 @@ """Functions used to generate source files during build time""" -import zlib +from collections import OrderedDict +from io import TextIOWrapper - -def escape_string(s): - def charcode_to_c_escapes(c): - rev_result = [] - while c >= 256: - c, low = (c // 256, c % 256) - rev_result.append("\\%03o" % low) - rev_result.append("\\%03o" % c) - return "".join(reversed(rev_result)) - - result = "" - if isinstance(s, str): - s = s.encode("utf-8") - for c in s: - if not (32 <= c < 127) or c in (ord("\\"), ord('"')): - result += charcode_to_c_escapes(c) - else: - result += chr(c) - return result +import methods def make_certs_header(target, source, env): - src = str(source[0]) - dst = str(target[0]) - with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: - buf = f.read() - decomp_size = len(buf) - - # Use maximum zlib compression level to further reduce file size - # (at the cost of initial build times). - buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef CERTS_COMPRESSED_GEN_H\n") - g.write("#define CERTS_COMPRESSED_GEN_H\n") + buffer = methods.get_buffer(str(source[0])) + decomp_size = len(buffer) + buffer = methods.compress_buffer(buffer) + with methods.generated_wrapper(str(target[0])) as file: # System certs path. Editor will use them if defined. (for package maintainers) - path = env["system_certs_path"] - g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path)) + file.write('#define _SYSTEM_CERTS_PATH "{}"\n'.format(env["system_certs_path"])) if env["builtin_certs"]: # Defined here and not in env so changing it does not trigger a full rebuild. - g.write("#define BUILTIN_CERTS_ENABLED\n") - g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n") - g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n") - g.write("static const unsigned char _certs_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif // CERTS_COMPRESSED_GEN_H") + file.write(f"""\ +#define BUILTIN_CERTS_ENABLED + +inline constexpr int _certs_compressed_size = {len(buffer)}; +inline constexpr int _certs_uncompressed_size = {decomp_size}; +inline constexpr unsigned char _certs_compressed[] = {{ + {methods.format_buffer(buffer, 1)} +}}; +""") def make_authors_header(target, source, env): - sections = [ - "Project Founders", - "Lead Developer", - "Project Manager", - "Developers", - ] - sections_id = [ - "AUTHORS_FOUNDERS", - "AUTHORS_LEAD_DEVELOPERS", - "AUTHORS_PROJECT_MANAGERS", - "AUTHORS_DEVELOPERS", - ] + SECTIONS = { + "Project Founders": "AUTHORS_FOUNDERS", + "Lead Developer": "AUTHORS_LEAD_DEVELOPERS", + "Project Manager": "AUTHORS_PROJECT_MANAGERS", + "Developers": "AUTHORS_DEVELOPERS", + } + buffer = methods.get_buffer(str(source[0])) + reading = False - src = str(source[0]) - dst = str(target[0]) - with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef AUTHORS_GEN_H\n") - g.write("#define AUTHORS_GEN_H\n") - - reading = False + with methods.generated_wrapper(str(target[0])) as file: def close_section(): - g.write("\t0\n") - g.write("};\n") + file.write("\tnullptr,\n};\n\n") - for line in f: - if reading: - if line.startswith(" "): - g.write('\t"' + escape_string(line.strip()) + '",\n') - continue - if line.startswith("## "): + for line in buffer.decode().splitlines(): + if line.startswith(" ") and reading: + file.write(f'\t"{methods.to_escaped_cstring(line).strip()}",\n') + elif line.startswith("## "): if reading: close_section() reading = False - for section, section_id in zip(sections, sections_id): - if line.strip().endswith(section): - current_section = escape_string(section_id) - reading = True - g.write("const char *const " + current_section + "[] = {\n") - break + section = SECTIONS[line[3:].strip()] + if section: + file.write(f"inline constexpr const char *{section}[] = {{\n") + reading = True if reading: close_section() - g.write("#endif // AUTHORS_GEN_H\n") - def make_donors_header(target, source, env): - sections = [ - "Patrons", - "Platinum sponsors", - "Gold sponsors", - "Silver sponsors", - "Diamond members", - "Titanium members", - "Platinum members", - "Gold members", - ] - sections_id = [ - "DONORS_PATRONS", - "DONORS_SPONSORS_PLATINUM", - "DONORS_SPONSORS_GOLD", - "DONORS_SPONSORS_SILVER", - "DONORS_MEMBERS_DIAMOND", - "DONORS_MEMBERS_TITANIUM", - "DONORS_MEMBERS_PLATINUM", - "DONORS_MEMBERS_GOLD", - ] + SECTIONS = { + "Patrons": "DONORS_PATRONS", + "Platinum sponsors": "DONORS_SPONSORS_PLATINUM", + "Gold sponsors": "DONORS_SPONSORS_GOLD", + "Silver sponsors": "DONORS_SPONSORS_SILVER", + "Diamond members": "DONORS_MEMBERS_DIAMOND", + "Titanium members": "DONORS_MEMBERS_TITANIUM", + "Platinum members": "DONORS_MEMBERS_PLATINUM", + "Gold members": "DONORS_MEMBERS_GOLD", + } + buffer = methods.get_buffer(str(source[0])) + reading = False - src = str(source[0]) - dst = str(target[0]) - with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef DONORS_GEN_H\n") - g.write("#define DONORS_GEN_H\n") - - reading = False + with methods.generated_wrapper(str(target[0])) as file: def close_section(): - g.write("\t0\n") - g.write("};\n") + file.write("\tnullptr,\n};\n\n") - for line in f: - if reading >= 0: - if line.startswith(" "): - g.write('\t"' + escape_string(line.strip()) + '",\n') - continue - if line.startswith("## "): + for line in buffer.decode().splitlines(): + if line.startswith(" ") and reading: + file.write(f'\t"{methods.to_escaped_cstring(line).strip()}",\n') + elif line.startswith("## "): if reading: close_section() reading = False - for section, section_id in zip(sections, sections_id): - if line.strip().endswith(section): - current_section = escape_string(section_id) - reading = True - g.write("const char *const " + current_section + "[] = {\n") - break + section = SECTIONS.get(line[3:].strip()) + if section: + file.write(f"inline constexpr const char *{section}[] = {{\n") + reading = True if reading: close_section() - g.write("#endif // DONORS_GEN_H\n") - def make_license_header(target, source, env): src_copyright = str(source[0]) src_license = str(source[1]) - dst = str(target[0]) class LicenseReader: - def __init__(self, license_file): + def __init__(self, license_file: TextIOWrapper): self._license_file = license_file self.line_num = 0 self.current = self.next_line() @@ -188,9 +121,7 @@ def make_license_header(target, source, env): lines.append(self.current.strip()) return (tag, lines) - from collections import OrderedDict - - projects: dict = OrderedDict() + projects = OrderedDict() license_list = [] with open(src_copyright, "r", encoding="utf-8") as copyright_file: @@ -212,7 +143,7 @@ def make_license_header(target, source, env): part = {} reader.next_line() - data_list: list = [] + data_list = [] for project in iter(projects.values()): for part in project: part["file_index"] = len(data_list) @@ -220,96 +151,76 @@ def make_license_header(target, source, env): part["copyright_index"] = len(data_list) data_list += part["Copyright"] - with open(dst, "w", encoding="utf-8", newline="\n") as f: - f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - f.write("#ifndef LICENSE_GEN_H\n") - f.write("#define LICENSE_GEN_H\n") - f.write("const char *const GODOT_LICENSE_TEXT =") + with open(src_license, "r", encoding="utf-8") as file: + license_text = file.read() - with open(src_license, "r", encoding="utf-8") as license_file: - for line in license_file: - escaped_string = escape_string(line.strip()) - f.write('\n\t\t"' + escaped_string + '\\n"') - f.write(";\n\n") + with methods.generated_wrapper(str(target[0])) as file: + file.write(f"""\ +inline constexpr const char *GODOT_LICENSE_TEXT = {{ +{methods.to_raw_cstring(license_text)} +}}; - f.write( - "struct ComponentCopyrightPart {\n" - "\tconst char *license;\n" - "\tconst char *const *files;\n" - "\tconst char *const *copyright_statements;\n" - "\tint file_count;\n" - "\tint copyright_count;\n" - "};\n\n" - ) +struct ComponentCopyrightPart {{ + const char *license; + const char *const *files; + const char *const *copyright_statements; + int file_count; + int copyright_count; +}}; - f.write( - "struct ComponentCopyright {\n" - "\tconst char *name;\n" - "\tconst ComponentCopyrightPart *parts;\n" - "\tint part_count;\n" - "};\n\n" - ) +struct ComponentCopyright {{ + const char *name; + const ComponentCopyrightPart *parts; + int part_count; +}}; - f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n") +""") + + file.write("inline constexpr const char *COPYRIGHT_INFO_DATA[] = {\n") for line in data_list: - f.write('\t"' + escape_string(line) + '",\n') - f.write("};\n\n") + file.write(f'\t"{methods.to_escaped_cstring(line)}",\n') + file.write("};\n\n") - f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n") + file.write("inline constexpr ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n") part_index = 0 part_indexes = {} for project_name, project in iter(projects.items()): part_indexes[project_name] = part_index for part in project: - f.write( - '\t{ "' - + escape_string(part["License"][0]) - + '", ' - + "©RIGHT_INFO_DATA[" - + str(part["file_index"]) - + "], " - + "©RIGHT_INFO_DATA[" - + str(part["copyright_index"]) - + "], " - + str(len(part["Files"])) - + ", " - + str(len(part["Copyright"])) - + " },\n" + file.write( + f'\t{{ "{methods.to_escaped_cstring(part["License"][0])}", ' + + f"©RIGHT_INFO_DATA[{part['file_index']}], " + + f"©RIGHT_INFO_DATA[{part['copyright_index']}], " + + f"{len(part['Files'])}, {len(part['Copyright'])} }},\n" ) part_index += 1 - f.write("};\n\n") + file.write("};\n\n") - f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n") + file.write(f"inline constexpr int COPYRIGHT_INFO_COUNT = {len(projects)};\n") - f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n") + file.write("inline constexpr ComponentCopyright COPYRIGHT_INFO[] = {\n") for project_name, project in iter(projects.items()): - f.write( - '\t{ "' - + escape_string(project_name) - + '", ' - + "©RIGHT_PROJECT_PARTS[" - + str(part_indexes[project_name]) - + "], " - + str(len(project)) - + " },\n" + file.write( + f'\t{{ "{methods.to_escaped_cstring(project_name)}", ' + + f"©RIGHT_PROJECT_PARTS[{part_indexes[project_name]}], " + + f"{len(project)} }},\n" ) - f.write("};\n\n") + file.write("};\n\n") - f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n") + file.write(f"inline constexpr int LICENSE_COUNT = {len(license_list)};\n") - f.write("const char *const LICENSE_NAMES[] = {\n") + file.write("inline constexpr const char *LICENSE_NAMES[] = {\n") for license in license_list: - f.write('\t"' + escape_string(license[0]) + '",\n') - f.write("};\n\n") + file.write(f'\t"{methods.to_escaped_cstring(license[0])}",\n') + file.write("};\n\n") - f.write("const char *const LICENSE_BODIES[] = {\n\n") + file.write("inline constexpr const char *LICENSE_BODIES[] = {\n\n") for license in license_list: + to_raw = [] for line in license[1:]: if line == ".": - f.write('\t"\\n"\n') + to_raw += [""] else: - f.write('\t"' + escape_string(line) + '\\n"\n') - f.write('\t"",\n\n') - f.write("};\n\n") - - f.write("#endif // LICENSE_GEN_H\n") + to_raw += [line] + file.write(f"{methods.to_raw_cstring(to_raw)},\n\n") + file.write("};\n\n") diff --git a/engine/core/core_constants.h b/engine/core/core_constants.h index 8ab4a78a..c432fdca 100644 --- a/engine/core/core_constants.h +++ b/engine/core/core_constants.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CORE_CONSTANTS_H -#define CORE_CONSTANTS_H +#pragma once #include "core/string/string_name.h" #include "core/templates/hash_map.h" @@ -47,5 +46,3 @@ public: static bool is_global_enum(const StringName &p_enum); static void get_enum_values(const StringName &p_enum, HashMap *p_values); }; - -#endif // CORE_CONSTANTS_H diff --git a/engine/core/core_globals.h b/engine/core/core_globals.h index ebb1f41a..63a6a5b1 100644 --- a/engine/core/core_globals.h +++ b/engine/core/core_globals.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CORE_GLOBALS_H -#define CORE_GLOBALS_H +#pragma once // Home for state needed from global functions // that cannot be stored in Engine or OS due to e.g. circular includes @@ -40,5 +39,3 @@ public: static bool print_line_enabled; static bool print_error_enabled; }; - -#endif // CORE_GLOBALS_H diff --git a/engine/core/core_string_names.h b/engine/core/core_string_names.h index be3bc38e..33203c5b 100644 --- a/engine/core/core_string_names.h +++ b/engine/core/core_string_names.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CORE_STRING_NAMES_H -#define CORE_STRING_NAMES_H +#pragma once #include "core/string/string_name.h" @@ -87,5 +86,3 @@ public: }; #define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name - -#endif // CORE_STRING_NAMES_H diff --git a/engine/core/crypto/SCsub b/engine/core/crypto/SCsub index 3cea6bfb..d33d119f 100644 --- a/engine/core/crypto/SCsub +++ b/engine/core/crypto/SCsub @@ -13,7 +13,7 @@ if is_builtin or not has_module: # Use our headers for builtin or if the module is not going to be compiled. # We decided not to depend on system mbedtls just for these few files that can # be easily extracted. - env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) + env_crypto.Prepend(CPPEXTPATH=["#thirdparty/mbedtls/include"]) # MbedTLS core functions (for CryptoCore). # If the mbedtls module is compiled we don't need to add the .c files with our diff --git a/engine/core/crypto/aes_context.h b/engine/core/crypto/aes_context.h index ab0792ac..2ae62c84 100644 --- a/engine/core/crypto/aes_context.h +++ b/engine/core/crypto/aes_context.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef AES_CONTEXT_H -#define AES_CONTEXT_H +#pragma once #include "core/crypto/crypto_core.h" #include "core/object/ref_counted.h" @@ -64,5 +63,3 @@ public: }; VARIANT_ENUM_CAST(AESContext::Mode); - -#endif // AES_CONTEXT_H diff --git a/engine/core/crypto/crypto.h b/engine/core/crypto/crypto.h index dc4441c9..9c752e77 100644 --- a/engine/core/crypto/crypto.h +++ b/engine/core/crypto/crypto.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CRYPTO_H -#define CRYPTO_H +#pragma once #include "core/crypto/hashing_context.h" #include "core/io/resource.h" @@ -167,5 +166,3 @@ public: virtual void get_recognized_extensions(const Ref &p_resource, List *p_extensions) const override; virtual bool recognize(const Ref &p_resource) const override; }; - -#endif // CRYPTO_H diff --git a/engine/core/crypto/crypto_core.cpp b/engine/core/crypto/crypto_core.cpp index 13852d51..9d2c346e 100644 --- a/engine/core/crypto/crypto_core.cpp +++ b/engine/core/crypto/crypto_core.cpp @@ -214,8 +214,8 @@ Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], con } // CryptoCore -String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { - int b64len = p_src_len / 3 * 4 + 4 + 1; +String CryptoCore::b64_encode_str(const uint8_t *p_src, size_t p_src_len) { + size_t b64len = p_src_len / 3 * 4 + 4 + 1; Vector b64buff; b64buff.resize(b64len); uint8_t *w64 = b64buff.ptrw(); @@ -225,27 +225,27 @@ String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { return ret ? String() : (const char *)&w64[0]; } -Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { +Error CryptoCore::b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { +Error CryptoCore::b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len) { int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); return ret ? FAILED : OK; } -Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { +Error CryptoCore::md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]) { int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { +Error CryptoCore::sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]) { int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); return ret ? FAILED : OK; } -Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { +Error CryptoCore::sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]) { int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); return ret ? FAILED : OK; } diff --git a/engine/core/crypto/crypto_core.h b/engine/core/crypto/crypto_core.h index 4a9ffda8..8ef50fbc 100644 --- a/engine/core/crypto/crypto_core.h +++ b/engine/core/crypto/crypto_core.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CRYPTO_CORE_H -#define CRYPTO_CORE_H +#pragma once #include "core/object/ref_counted.h" @@ -107,13 +106,11 @@ public: Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst); }; - static String b64_encode_str(const uint8_t *p_src, int p_src_len); - static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); - static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + static String b64_encode_str(const uint8_t *p_src, size_t p_src_len); + static Error b64_encode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); + static Error b64_decode(uint8_t *r_dst, size_t p_dst_len, size_t *r_len, const uint8_t *p_src, size_t p_src_len); - static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); - static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); - static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); + static Error md5(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[16]); + static Error sha1(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[20]); + static Error sha256(const uint8_t *p_src, size_t p_src_len, unsigned char r_hash[32]); }; - -#endif // CRYPTO_CORE_H diff --git a/engine/core/crypto/hashing_context.h b/engine/core/crypto/hashing_context.h index 436afd83..6c9de6a8 100644 --- a/engine/core/crypto/hashing_context.h +++ b/engine/core/crypto/hashing_context.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef HASHING_CONTEXT_H -#define HASHING_CONTEXT_H +#pragma once #include "core/object/ref_counted.h" @@ -62,5 +61,3 @@ public: }; VARIANT_ENUM_CAST(HashingContext::HashType); - -#endif // HASHING_CONTEXT_H diff --git a/engine/core/debugger/debugger_marshalls.cpp b/engine/core/debugger/debugger_marshalls.cpp index cc36ca48..55b61f1c 100644 --- a/engine/core/debugger/debugger_marshalls.cpp +++ b/engine/core/debugger/debugger_marshalls.cpp @@ -36,8 +36,7 @@ #define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size())) Array DebuggerMarshalls::ScriptStackDump::serialize() { - Array arr; - arr.push_back(frames.size() * 3); + Array arr = { frames.size() * 3 }; for (const ScriptLanguage::StackInfo &frame : frames) { arr.push_back(frame.file); arr.push_back(frame.line); @@ -64,10 +63,7 @@ bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) { } Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) { - Array arr; - arr.push_back(name); - arr.push_back(type); - arr.push_back(value.get_type()); + Array arr = { name, type, value.get_type() }; Variant var = value; if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) { @@ -99,20 +95,20 @@ bool DebuggerMarshalls::ScriptStackVariable::deserialize(const Array &p_arr) { } Array DebuggerMarshalls::OutputError::serialize() { - Array arr; - arr.push_back(hr); - arr.push_back(min); - arr.push_back(sec); - arr.push_back(msec); - arr.push_back(source_file); - arr.push_back(source_func); - arr.push_back(source_line); - arr.push_back(error); - arr.push_back(error_descr); - arr.push_back(warning); unsigned int size = callstack.size(); + Array arr = { + hr, + min, + sec, msec, + source_file, + source_func, + source_line, + error, + error_descr, + warning, + size * 3 + }; const ScriptLanguage::StackInfo *r = callstack.ptr(); - arr.push_back(size * 3); for (int i = 0; i < callstack.size(); i++) { arr.push_back(r[i].file); arr.push_back(r[i].func); diff --git a/engine/core/debugger/debugger_marshalls.h b/engine/core/debugger/debugger_marshalls.h index 1072ddae..c661ef39 100644 --- a/engine/core/debugger/debugger_marshalls.h +++ b/engine/core/debugger/debugger_marshalls.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DEBUGGER_MARSHALLS_H -#define DEBUGGER_MARSHALLS_H +#pragma once #include "core/input/shortcut.h" #include "core/object/script_language.h" @@ -73,5 +72,3 @@ struct DebuggerMarshalls { static Array serialize_key_shortcut(const Ref &p_shortcut); static Ref deserialize_key_shortcut(const Array &p_keys); }; - -#endif // DEBUGGER_MARSHALLS_H diff --git a/engine/core/debugger/engine_debugger.cpp b/engine/core/debugger/engine_debugger.cpp index a9f87ad8..8d0f5261 100644 --- a/engine/core/debugger/engine_debugger.cpp +++ b/engine/core/debugger/engine_debugger.cpp @@ -127,7 +127,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, singleton->poll_events(true); } -void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()) { +void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()) { register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more. if (p_uri.is_empty()) { return; @@ -149,8 +149,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co singleton = memnew(RemoteDebugger(Ref(peer))); script_debugger = memnew(ScriptDebugger); // Notify editor of our pid (to allow focus stealing). - Array msg; - msg.push_back(OS::get_singleton()->get_process_id()); + Array msg = { OS::get_singleton()->get_process_id() }; singleton->send_message("set_pid", msg); } if (!singleton) { @@ -160,13 +159,14 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co // There is a debugger, parse breakpoints. ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger(); singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints); + singleton_script_debugger->set_ignore_error_breaks(p_ignore_error_breaks); for (int i = 0; i < p_breakpoints.size(); i++) { const String &bp = p_breakpoints[i]; int sp = bp.rfind_char(':'); ERR_CONTINUE_MSG(sp == -1, vformat("Invalid breakpoint: '%s', expected file:line format.", bp)); - singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp)); + singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1).to_int(), bp.substr(0, sp)); } allow_focus_steal_fn = p_allow_focus_steal_fn; diff --git a/engine/core/debugger/engine_debugger.h b/engine/core/debugger/engine_debugger.h index 1822915f..cfe1b6e3 100644 --- a/engine/core/debugger/engine_debugger.h +++ b/engine/core/debugger/engine_debugger.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ENGINE_DEBUGGER_H -#define ENGINE_DEBUGGER_H +#pragma once #include "core/string/string_name.h" #include "core/string/ustring.h" @@ -107,7 +106,7 @@ public: _FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; } - static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()); + static void initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector &p_breakpoints, void (*p_allow_focus_steal_fn)()); static void deinitialize(); static void register_profiler(const StringName &p_name, const Profiler &p_profiler); static void unregister_profiler(const StringName &p_name); @@ -140,5 +139,3 @@ public: virtual ~EngineDebugger(); }; - -#endif // ENGINE_DEBUGGER_H diff --git a/engine/core/debugger/engine_profiler.h b/engine/core/debugger/engine_profiler.h index d3d0021e..f74d20b8 100644 --- a/engine/core/debugger/engine_profiler.h +++ b/engine/core/debugger/engine_profiler.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ENGINE_PROFILER_H -#define ENGINE_PROFILER_H +#pragma once #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -59,5 +58,3 @@ public: EngineProfiler() {} virtual ~EngineProfiler(); }; - -#endif // ENGINE_PROFILER_H diff --git a/engine/core/debugger/local_debugger.cpp b/engine/core/debugger/local_debugger.cpp index a5d807f6..47a6d15d 100644 --- a/engine/core/debugger/local_debugger.cpp +++ b/engine/core/debugger/local_debugger.cpp @@ -242,7 +242,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (line.begins_with("br") || line.begins_with("break")) { if (line.get_slice_count(" ") <= 1) { const HashMap> &breakpoints = script_debugger->get_breakpoints(); - if (breakpoints.size() == 0) { + if (breakpoints.is_empty()) { print_line("No Breakpoints."); continue; } diff --git a/engine/core/debugger/local_debugger.h b/engine/core/debugger/local_debugger.h index 13c975c4..5c603e5f 100644 --- a/engine/core/debugger/local_debugger.h +++ b/engine/core/debugger/local_debugger.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef LOCAL_DEBUGGER_H -#define LOCAL_DEBUGGER_H +#pragma once #include "core/debugger/engine_debugger.h" #include "core/object/script_language.h" @@ -55,5 +54,3 @@ public: LocalDebugger(); ~LocalDebugger(); }; - -#endif // LOCAL_DEBUGGER_H diff --git a/engine/core/debugger/remote_debugger.cpp b/engine/core/debugger/remote_debugger.cpp index f8e42e6d..d14ea59a 100644 --- a/engine/core/debugger/remote_debugger.cpp +++ b/engine/core/debugger/remote_debugger.cpp @@ -95,10 +95,7 @@ public: }; Error RemoteDebugger::_put_msg(const String &p_message, const Array &p_data) { - Array msg; - msg.push_back(p_message); - msg.push_back(Thread::get_caller_id()); - msg.push_back(p_data); + Array msg = { p_message, Thread::get_caller_id(), p_data }; Error err = peer->put_message(msg); if (err != OK) { n_messages_dropped++; @@ -235,9 +232,7 @@ void RemoteDebugger::flush_output() { types.push_back(MESSAGE_TYPE_LOG); } - Array arr; - arr.push_back(strings); - arr.push_back(types); + Array arr = { strings, types }; _put_msg("output", arr); output_strings.clear(); } @@ -413,17 +408,25 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } ScriptLanguage *script_lang = script_debugger->get_break_language(); - const String error_str = script_lang ? script_lang->debug_get_error() : ""; - Array msg; - msg.push_back(p_can_continue); - msg.push_back(error_str); ERR_FAIL_NULL(script_lang); - msg.push_back(script_lang->debug_get_stack_level_count() > 0); - msg.push_back(Thread::get_caller_id() == Thread::get_main_id() ? String(RTR("Main Thread")) : itos(Thread::get_caller_id())); - if (allow_focus_steal_fn) { - allow_focus_steal_fn(); + const bool can_break = !(p_is_error_breakpoint && script_debugger->is_ignoring_error_breaks()); + const String error_str = script_lang ? script_lang->debug_get_error() : ""; + + if (can_break) { + Array msg = { + p_can_continue, + error_str, + script_lang->debug_get_stack_level_count() > 0, + Thread::get_caller_id() + }; + if (allow_focus_steal_fn) { + allow_focus_steal_fn(); + } + send_message("debug_enter", msg); + } else { + ERR_PRINT(error_str); + return; } - send_message("debug_enter", msg); Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE; @@ -507,8 +510,7 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { script_lang->debug_get_globals(&globals, &globals_vals); ERR_FAIL_COND(globals.size() != globals_vals.size()); - Array var_size; - var_size.push_back(local_vals.size() + member_vals.size() + globals_vals.size()); + Array var_size = { local_vals.size() + member_vals.size() + globals_vals.size() }; send_message("stack_frame_vars", var_size); _send_stack_vars(locals, local_vals, 0); _send_stack_vars(members, member_vals, 1); @@ -530,6 +532,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (command == "set_skip_breakpoints") { ERR_FAIL_COND(data.is_empty()); script_debugger->set_skip_breakpoints(data[0]); + } else if (command == "set_ignore_error_breaks") { + ERR_FAIL_COND(data.is_empty()); + script_debugger->set_ignore_error_breaks(data[0]); } else if (command == "evaluate") { String expression_str = data[0]; int frame = data[1]; @@ -669,6 +674,9 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo } else if (p_cmd == "set_skip_breakpoints") { ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); script_debugger->set_skip_breakpoints(p_data[0]); + } else if (p_cmd == "set_ignore_error_breaks") { + ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA); + script_debugger->set_ignore_error_breaks(p_data[0]); } else if (p_cmd == "break") { script_debugger->debug(script_debugger->get_break_language()); } else { diff --git a/engine/core/debugger/remote_debugger.h b/engine/core/debugger/remote_debugger.h index e91d09be..cbac2257 100644 --- a/engine/core/debugger/remote_debugger.h +++ b/engine/core/debugger/remote_debugger.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef REMOTE_DEBUGGER_H -#define REMOTE_DEBUGGER_H +#pragma once #include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" @@ -122,5 +121,3 @@ public: explicit RemoteDebugger(Ref p_peer); ~RemoteDebugger(); }; - -#endif // REMOTE_DEBUGGER_H diff --git a/engine/core/debugger/remote_debugger_peer.cpp b/engine/core/debugger/remote_debugger_peer.cpp index 1afb7fe0..011e6722 100644 --- a/engine/core/debugger/remote_debugger_peer.cpp +++ b/engine/core/debugger/remote_debugger_peer.cpp @@ -96,7 +96,7 @@ void RemoteDebuggerPeerTCP::_write_out() { while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_OUT) == OK) { uint8_t *buf = out_buf.ptrw(); if (out_left <= 0) { - if (out_queue.size() == 0) { + if (out_queue.is_empty()) { break; // Nothing left to send } mutex.lock(); diff --git a/engine/core/debugger/remote_debugger_peer.h b/engine/core/debugger/remote_debugger_peer.h index 37da0a92..3b171e4b 100644 --- a/engine/core/debugger/remote_debugger_peer.h +++ b/engine/core/debugger/remote_debugger_peer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef REMOTE_DEBUGGER_PEER_H -#define REMOTE_DEBUGGER_PEER_H +#pragma once #include "core/io/stream_peer_tcp.h" #include "core/object/ref_counted.h" @@ -92,5 +91,3 @@ public: RemoteDebuggerPeerTCP(Ref p_stream = Ref()); ~RemoteDebuggerPeerTCP(); }; - -#endif // REMOTE_DEBUGGER_PEER_H diff --git a/engine/core/debugger/script_debugger.cpp b/engine/core/debugger/script_debugger.cpp index e7d8654a..e522d9ba 100644 --- a/engine/core/debugger/script_debugger.cpp +++ b/engine/core/debugger/script_debugger.cpp @@ -58,7 +58,7 @@ void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) { } breakpoints[p_line].erase(p_source); - if (breakpoints[p_line].size() == 0) { + if (breakpoints[p_line].is_empty()) { breakpoints.erase(p_line); } } @@ -79,6 +79,14 @@ bool ScriptDebugger::is_skipping_breakpoints() { return skip_breakpoints; } +void ScriptDebugger::set_ignore_error_breaks(bool p_ignore) { + ignore_error_breaks = p_ignore; +} + +bool ScriptDebugger::is_ignoring_error_breaks() { + return ignore_error_breaks; +} + void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_is_error_breakpoint) { ScriptLanguage *prev = break_lang; break_lang = p_lang; diff --git a/engine/core/debugger/script_debugger.h b/engine/core/debugger/script_debugger.h index fb786f1b..0a5ffe78 100644 --- a/engine/core/debugger/script_debugger.h +++ b/engine/core/debugger/script_debugger.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef SCRIPT_DEBUGGER_H -#define SCRIPT_DEBUGGER_H +#pragma once #include "core/object/script_language.h" #include "core/string/string_name.h" @@ -40,6 +39,7 @@ class ScriptDebugger { typedef ScriptLanguage::StackInfo StackInfo; bool skip_breakpoints = false; + bool ignore_error_breaks = false; HashMap> breakpoints; @@ -64,6 +64,8 @@ public: ScriptLanguage *get_break_language() { return break_lang; } void set_skip_breakpoints(bool p_skip_breakpoints); bool is_skipping_breakpoints(); + void set_ignore_error_breaks(bool p_ignore); + bool is_ignoring_error_breaks(); void insert_breakpoint(int p_line, const StringName &p_source); void remove_breakpoint(int p_line, const StringName &p_source); _ALWAYS_INLINE_ bool is_breakpoint(int p_line, const StringName &p_source) const { @@ -82,5 +84,3 @@ public: Vector get_error_stack_info() const; ScriptDebugger() {} }; - -#endif // SCRIPT_DEBUGGER_H diff --git a/engine/core/doc_data.cpp b/engine/core/doc_data.cpp index 28814435..d1904025 100644 --- a/engine/core/doc_data.cpp +++ b/engine/core/doc_data.cpp @@ -32,11 +32,11 @@ String DocData::get_default_value_string(const Variant &p_value) { if (p_value.get_type() == Variant::ARRAY) { - return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace("\n", " "); + return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' '); } else if (p_value.get_type() == Variant::DICTIONARY) { - return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace("\n", " "); + return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace_char('\n', ' '); } else { - return p_value.get_construct_string().replace("\n", " "); + return p_value.get_construct_string().replace_char('\n', ' '); } } @@ -51,7 +51,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { p_method.return_enum = p_retinfo.class_name; if (p_method.return_enum.begins_with("_")) { //proxy class - p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); + p_method.return_enum = p_method.return_enum.substr(1); } p_method.return_is_bitfield = p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD; p_method.return_type = "int"; @@ -85,7 +85,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) { p_argument.enumeration = p_arginfo.class_name; if (p_argument.enumeration.begins_with("_")) { //proxy class - p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); + p_argument.enumeration = p_argument.enumeration.substr(1); } p_argument.is_bitfield = p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD; p_argument.type = "int"; @@ -136,11 +136,10 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met return_doc_from_retinfo(p_method, p_methodinfo.return_val); - int i = 0; - for (List::ConstIterator itr = p_methodinfo.arguments.begin(); itr != p_methodinfo.arguments.end(); ++itr, ++i) { + for (int64_t i = 0; i < p_methodinfo.arguments.size(); ++i) { DocData::ArgumentDoc argument; - argument_doc_from_arginfo(argument, *itr); - int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); + argument_doc_from_arginfo(argument, p_methodinfo.arguments[i]); + int64_t default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); if (default_arg_index >= 0) { Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; argument.default_value = get_default_value_string(default_arg); diff --git a/engine/core/doc_data.h b/engine/core/doc_data.h index 49f9c3aa..50e67ec7 100644 --- a/engine/core/doc_data.h +++ b/engine/core/doc_data.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DOC_DATA_H -#define DOC_DATA_H +#pragma once #include "core/io/xml_parser.h" #include "core/variant/variant.h" @@ -115,7 +114,7 @@ public: // Must be an operator or a constructor since there is no other overloading if (name.left(8) == "operator") { if (arguments.size() == p_method.arguments.size()) { - if (arguments.size() == 0) { + if (arguments.is_empty()) { return false; } return arguments[0].type < p_method.arguments[0].type; @@ -127,7 +126,7 @@ public: // - 1. Default constructor: Foo() // - 2. Copy constructor: Foo(Foo) // - 3+. Other constructors Foo(Bar, ...) based on first argument's name - if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1. + if (arguments.is_empty() || p_method.arguments.is_empty()) { // 1. return arguments.size() < p_method.arguments.size(); } if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2. @@ -795,8 +794,8 @@ public: if (p_dict.has("enums")) { enums = p_dict["enums"]; } - for (int i = 0; i < enums.size(); i++) { - doc.enums[enums.get_key_at_index(i)] = EnumDoc::from_dict(enums.get_value_at_index(i)); + for (const KeyValue &kv : enums) { + doc.enums[kv.key] = EnumDoc::from_dict(kv.value); } Array properties; @@ -980,5 +979,3 @@ public: static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo); static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc); }; - -#endif // DOC_DATA_H diff --git a/engine/core/error/error_list.cpp b/engine/core/error/error_list.cpp index f14cc84b..13e560c3 100644 --- a/engine/core/error/error_list.cpp +++ b/engine/core/error/error_list.cpp @@ -30,6 +30,8 @@ #include "error_list.h" +#include + const char *error_names[] = { "OK", // OK "Failed", // FAILED @@ -82,4 +84,4 @@ const char *error_names[] = { "Printer on fire", // ERR_PRINTER_ON_FIRE }; -static_assert(sizeof(error_names) / sizeof(*error_names) == ERR_MAX); +static_assert(std::size(error_names) == ERR_MAX); diff --git a/engine/core/error/error_list.h b/engine/core/error/error_list.h index cdf06eb0..cdc31ecd 100644 --- a/engine/core/error/error_list.h +++ b/engine/core/error/error_list.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ERROR_LIST_H -#define ERROR_LIST_H +#pragma once /** Error List. Please never compare an error against FAILED * Either do result != OK , or !result. This way, Error fail @@ -98,5 +97,3 @@ enum Error { }; extern const char *error_names[]; - -#endif // ERROR_LIST_H diff --git a/engine/core/error/error_macros.cpp b/engine/core/error/error_macros.cpp index a2369992..74dc9336 100644 --- a/engine/core/error/error_macros.cpp +++ b/engine/core/error/error_macros.cpp @@ -31,6 +31,7 @@ #include "error_macros.h" #include "core/io/logger.h" +#include "core/object/object_id.h" #include "core/os/os.h" #include "core/string/ustring.h" @@ -187,7 +188,7 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file, } else { String node_name; if (p_id.is_valid()) { - Node *node = Object::cast_to(ObjectDB::get_instance(p_id)); + Node *node = ObjectDB::get_instance(p_id); if (node && node->is_inside_tree()) { node_name = "\"" + String(node->get_path()) + "\""; } else { diff --git a/engine/core/error/error_macros.h b/engine/core/error/error_macros.h index 752fd605..bedb84b4 100644 --- a/engine/core/error/error_macros.h +++ b/engine/core/error/error_macros.h @@ -28,15 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ERROR_MACROS_H -#define ERROR_MACROS_H +#pragma once -#include "core/object/object_id.h" #include "core/typedefs.h" -#include // We'd normally use safe_refcount.h, but that would cause circular includes. +#include // IWYU pragma: keep // Used in macro. We'd normally use `safe_refcount.h`, but that would cause circular includes. class String; +class ObjectID; enum ErrorHandlerType { ERR_HANDLER_ERROR, @@ -62,16 +61,16 @@ void add_error_handler(ErrorHandlerList *p_handler); void remove_error_handler(const ErrorHandlerList *p_handler); // Functions used by the error macros. -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); +_NO_INLINE_ void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR); void _err_print_error_asap(const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR); -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false); -void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false); -void _err_flush_stdout(); +_NO_INLINE_ void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false); +_NO_INLINE_ void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false); +_NO_INLINE_ void _err_flush_stdout(); void _physics_interpolation_warning(const char *p_function, const char *p_file, int p_line, ObjectID p_id, const char *p_warn_string); @@ -845,5 +844,3 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file, #define PHYSICS_INTERPOLATION_WARNING(m_string) \ _physics_interpolation_warning(FUNCTION_STR, __FILE__, __LINE__, ObjectID(UINT64_MAX), m_string) - -#endif // ERROR_MACROS_H diff --git a/engine/core/extension/extension_api_dump.cpp b/engine/core/extension/extension_api_dump.cpp index 52f1672a..93b1b272 100644 --- a/engine/core/extension/extension_api_dump.cpp +++ b/engine/core/extension/extension_api_dump.cpp @@ -96,8 +96,7 @@ static String fix_doc_description(const String &p_bbcode) { // Based on what EditorHelp does. return p_bbcode.dedent() - .replace("\t", "") - .replace("\r", "") + .remove_chars("\t\r") .strip_edges(); } @@ -107,16 +106,22 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { { //header Dictionary header; - header["version_major"] = VERSION_MAJOR; - header["version_minor"] = VERSION_MINOR; -#if VERSION_PATCH - header["version_patch"] = VERSION_PATCH; + header["version_major"] = GODOT_VERSION_MAJOR; + header["version_minor"] = GODOT_VERSION_MINOR; +#if GODOT_VERSION_PATCH + header["version_patch"] = GODOT_VERSION_PATCH; #else header["version_patch"] = 0; #endif - header["version_status"] = VERSION_STATUS; - header["version_build"] = VERSION_BUILD; - header["version_full_name"] = VERSION_FULL_NAME; + header["version_status"] = GODOT_VERSION_STATUS; + header["version_build"] = GODOT_VERSION_BUILD; + header["version_full_name"] = GODOT_VERSION_FULL_NAME; + +#if REAL_T_IS_DOUBLE + header["precision"] = "double"; +#else + header["precision"] = "single"; +#endif api_dump["header"] = header; } @@ -278,43 +283,43 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { #define REAL_MEMBER_OFFSET(type, member) \ { \ type, \ - member, \ - "float", \ - sizeof(float), \ - "float", \ - sizeof(float), \ - "double", \ - sizeof(double), \ - "double", \ - sizeof(double), \ + member, \ + "float", \ + sizeof(float), \ + "float", \ + sizeof(float), \ + "double", \ + sizeof(double), \ + "double", \ + sizeof(double), \ } #define INT32_MEMBER_OFFSET(type, member) \ { \ type, \ - member, \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ - "int32", \ - sizeof(int32_t), \ + member, \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ + "int32", \ + sizeof(int32_t), \ } #define INT32_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \ { \ type, \ - member, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ - member_type, \ - sizeof(int32_t) * member_elems, \ + member, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ + member_type, \ + sizeof(int32_t) * member_elems, \ } #define REAL_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \ @@ -970,14 +975,14 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { Array values; List enum_constant_list; ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true); - for (List::Element *G = enum_constant_list.front(); G; G = G->next()) { + for (const StringName &enum_constant : enum_constant_list) { Dictionary d3; - d3["name"] = String(G->get()); - d3["value"] = ClassDB::get_integer_constant(class_name, G->get()); + d3["name"] = String(enum_constant); + d3["value"] = ClassDB::get_integer_constant(class_name, enum_constant); if (p_include_docs) { for (const DocData::ConstantDoc &constant_doc : class_doc->constants) { - if (constant_doc.name == G->get()) { + if (constant_doc.name == enum_constant) { d3["description"] = fix_doc_description(constant_doc.description); break; } @@ -1048,9 +1053,8 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { } Array arguments; - int i = 0; - for (List::ConstIterator itr = mi.arguments.begin(); itr != mi.arguments.end(); ++itr, ++i) { - const PropertyInfo &pinfo = *itr; + for (int64_t i = 0; i < mi.arguments.size(); ++i) { + const PropertyInfo &pinfo = mi.arguments[i]; Dictionary d3; d3["name"] = pinfo.name; @@ -1175,11 +1179,10 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { Array arguments; - int i = 0; - for (List::ConstIterator itr = F.arguments.begin(); itr != F.arguments.end(); ++itr, ++i) { + for (int64_t i = 0; i < F.arguments.size(); ++i) { Dictionary d3; - d3["name"] = itr->name; - d3["type"] = get_property_info_type_name(*itr); + d3["name"] = F.arguments[i].name; + d3["type"] = get_property_info_type_name(F.arguments[i]); if (F.get_argument_meta(i) > 0) { d3["meta"] = get_type_meta_name((GodotTypeInfo::Metadata)F.get_argument_meta(i)); } @@ -1340,16 +1343,16 @@ static bool compare_value(const String &p_path, const String &p_field, const Var } else if (p_old_value.get_type() == Variant::DICTIONARY && p_new_value.get_type() == Variant::DICTIONARY) { Dictionary old_dict = p_old_value; Dictionary new_dict = p_new_value; - for (const Variant &key : old_dict.keys()) { - if (!new_dict.has(key)) { + for (const KeyValue &kv : old_dict) { + if (!new_dict.has(kv.key)) { failed = true; - print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, key)); + print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, kv.key)); continue; } - if (p_allow_name_change && key == "name") { + if (p_allow_name_change && kv.key == "name") { continue; } - if (!compare_value(path, key, old_dict[key], new_dict[key], p_allow_name_change)) { + if (!compare_value(path, kv.key, kv.value, new_dict[kv.key], p_allow_name_change)) { failed = true; } } @@ -1420,25 +1423,25 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ bool optional = field.begins_with("*"); if (optional) { // This is an optional field, but if exists it has to exist in both. - field = field.substr(1, field.length()); + field = field.substr(1); } bool added = field.begins_with("+"); if (added) { // Meaning this field must either exist or contents may not exist. - field = field.substr(1, field.length()); + field = field.substr(1); } bool enum_values = field.begins_with("$"); if (enum_values) { // Meaning this field is a list of enum values. - field = field.substr(1, field.length()); + field = field.substr(1); } bool allow_name_change = field.begins_with("@"); if (allow_name_change) { // Meaning that when structurally comparing the old and new value, the dictionary entry 'name' may change. - field = field.substr(1, field.length()); + field = field.substr(1); } Variant old_value; @@ -1598,8 +1601,8 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) { int major = header["version_major"]; int minor = header["version_minor"]; - ERR_FAIL_COND_V_MSG(major != VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, VERSION_MAJOR)); - ERR_FAIL_COND_V_MSG(minor > VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor)); + ERR_FAIL_COND_V_MSG(major != GODOT_VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, GODOT_VERSION_MAJOR)); + ERR_FAIL_COND_V_MSG(minor > GODOT_VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor)); } bool failed = false; diff --git a/engine/core/extension/extension_api_dump.h b/engine/core/extension/extension_api_dump.h index 204a115f..027a8d91 100644 --- a/engine/core/extension/extension_api_dump.h +++ b/engine/core/extension/extension_api_dump.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef EXTENSION_API_DUMP_H -#define EXTENSION_API_DUMP_H +#pragma once #include "core/extension/gdextension.h" @@ -42,5 +41,3 @@ public: static Error validate_extension_json_file(const String &p_path); }; #endif - -#endif // EXTENSION_API_DUMP_H diff --git a/engine/core/extension/gdextension.cpp b/engine/core/extension/gdextension.cpp index f40612ec..ea314b71 100644 --- a/engine/core/extension/gdextension.cpp +++ b/engine/core/extension/gdextension.cpp @@ -679,6 +679,13 @@ void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExte memnew_placement(r_path, String(library_path)); } +void GDExtension::_register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback) { +#ifdef TOOLS_ENABLED + GDExtension *self = reinterpret_cast(p_library); + self->get_classes_used_callback = p_callback; +#endif +} + HashMap GDExtension::gdextension_interface_functions; void GDExtension::register_interface_function(const StringName &p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) { @@ -799,6 +806,7 @@ void GDExtension::initialize_gdextensions() { register_interface_function("classdb_register_extension_class_signal", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_signal); register_interface_function("classdb_unregister_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_unregister_extension_class); register_interface_function("get_library_path", (GDExtensionInterfaceFunctionPtr)&GDExtension::_get_library_path); + register_interface_function("editor_register_get_classes_used_callback", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_get_classes_used_callback); } void GDExtension::finalize_gdextensions() { @@ -1034,6 +1042,14 @@ void GDExtension::_untrack_instance(void *p_user_data, void *p_instance) { extension->instances.erase(obj->get_instance_id()); } +PackedStringArray GDExtension::get_classes_used() const { + PackedStringArray ret; + if (get_classes_used_callback) { + get_classes_used_callback((GDExtensionTypePtr)&ret); + } + return ret; +} + Vector GDExtensionEditorPlugins::extension_classes; GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_add_plugin = nullptr; GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr; diff --git a/engine/core/extension/gdextension.h b/engine/core/extension/gdextension.h index bfed8424..a40f7af4 100644 --- a/engine/core/extension/gdextension.h +++ b/engine/core/extension/gdextension.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_H -#define GDEXTENSION_H +#pragma once #include "core/extension/gdextension_interface.h" #include "core/extension/gdextension_loader.h" @@ -94,6 +93,7 @@ class GDExtension : public Resource { static void _register_extension_class_signal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count); static void _unregister_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); static void _get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path); + static void _register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback); GDExtensionInitialization initialization; int32_t level_initialized = -1; @@ -102,6 +102,7 @@ class GDExtension : public Resource { bool is_reloading = false; Vector invalid_methods; Vector instance_bindings; + GDExtensionEditorGetClassesUsedCallback get_classes_used_callback = nullptr; static void _track_instance(void *p_user_data, void *p_instance); static void _untrack_instance(void *p_user_data, void *p_instance); @@ -156,6 +157,8 @@ public: void track_instance_binding(Object *p_object); void untrack_instance_binding(Object *p_object); + + PackedStringArray get_classes_used() const; #endif InitializationLevel get_minimum_library_initialization_level() const; @@ -226,5 +229,3 @@ public: }; #endif // TOOLS_ENABLED - -#endif // GDEXTENSION_H diff --git a/engine/core/extension/gdextension_interface.cpp b/engine/core/extension/gdextension_interface.cpp index 30f0ce98..725475d9 100644 --- a/engine/core/extension/gdextension_interface.cpp +++ b/engine/core/extension/gdextension_interface.cpp @@ -241,11 +241,25 @@ GDExtensionInterfaceFunctionPtr gdextension_get_proc_address(const char *p_name) return GDExtension::get_interface_function(p_name); } +#ifndef DISABLE_DEPRECATED static void gdextension_get_godot_version(GDExtensionGodotVersion *r_godot_version) { - r_godot_version->major = VERSION_MAJOR; - r_godot_version->minor = VERSION_MINOR; - r_godot_version->patch = VERSION_PATCH; - r_godot_version->string = VERSION_FULL_NAME; + r_godot_version->major = GODOT_VERSION_MAJOR; + r_godot_version->minor = GODOT_VERSION_MINOR; + r_godot_version->patch = GODOT_VERSION_PATCH; + r_godot_version->string = GODOT_VERSION_FULL_NAME; +} +#endif + +static void gdextension_get_godot_version2(GDExtensionGodotVersion2 *r_godot_version) { + r_godot_version->major = GODOT_VERSION_MAJOR; + r_godot_version->minor = GODOT_VERSION_MINOR; + r_godot_version->patch = GODOT_VERSION_PATCH; + r_godot_version->hex = GODOT_VERSION_HEX; + r_godot_version->status = GODOT_VERSION_STATUS; + r_godot_version->build = GODOT_VERSION_BUILD; + r_godot_version->hash = GODOT_VERSION_HASH; + r_godot_version->timestamp = GODOT_VERSION_TIMESTAMP; + r_godot_version->string = GODOT_VERSION_FULL_NAME; } // Memory Functions @@ -858,84 +872,82 @@ static GDExtensionPtrUtilityFunction gdextension_variant_get_ptr_utility_functio //string helpers static void gdextension_string_new_with_latin1_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { - memnew_placement(r_dest, String(p_contents)); + String *dest = memnew_placement(r_dest, String); + dest->append_latin1(Span(p_contents, p_contents ? strlen(p_contents) : 0)); } static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf8(p_contents); + String *dest = memnew_placement(r_dest, String); + dest->append_utf8(p_contents); } static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf16(p_contents); + String *dest = memnew_placement(r_dest, String); + dest->append_utf16(p_contents); } static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) { - memnew_placement(r_dest, String((const char32_t *)p_contents)); + String *dest = memnew_placement(r_dest, String); + dest->append_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0)); } static void gdextension_string_new_with_wide_chars(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents) { if constexpr (sizeof(wchar_t) == 2) { - // wchar_t is 16 bit, parse. - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf16((const char16_t *)p_contents); + // wchar_t is 16 bit (UTF-16). + String *dest = memnew_placement(r_dest, String); + dest->append_utf16((const char16_t *)p_contents); } else { - // wchar_t is 32 bit, copy. - memnew_placement(r_dest, String((const char32_t *)p_contents)); + // wchar_t is 32 bit (UTF-32). + String *string = memnew_placement(r_dest, String); + string->append_utf32(Span((const char32_t *)p_contents, p_contents ? strlen(p_contents) : 0)); } } static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - memnew_placement(r_dest, String(p_contents, p_size)); + String *dest = memnew_placement(r_dest, String); + dest->append_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0)); } static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf8(p_contents, p_size); + String *dest = memnew_placement(r_dest, String); + dest->append_utf8(p_contents, p_size); } static GDExtensionInt gdextension_string_new_with_utf8_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - return (GDExtensionInt)dest->parse_utf8(p_contents, p_size); + String *dest = memnew_placement(r_dest, String); + return (GDExtensionInt)dest->append_utf8(p_contents, p_size); } static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf16(p_contents, p_char_count); + String *dest = memnew_placement(r_dest, String); + dest->append_utf16(p_contents, p_char_count); } static GDExtensionInt gdextension_string_new_with_utf16_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian) { - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - return (GDExtensionInt)dest->parse_utf16(p_contents, p_char_count, p_default_little_endian); + String *dest = memnew_placement(r_dest, String); + return (GDExtensionInt)dest->append_utf16(p_contents, p_char_count, p_default_little_endian); } static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count) { - memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count)); + String *string = memnew_placement(r_dest, String); + string->append_utf32(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_char_count) : 0)); } static void gdextension_string_new_with_wide_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count) { if constexpr (sizeof(wchar_t) == 2) { - // wchar_t is 16 bit, parse. - memnew_placement(r_dest, String); - String *dest = reinterpret_cast(r_dest); - dest->parse_utf16((const char16_t *)p_contents, p_char_count); + // wchar_t is 16 bit (UTF-16). + String *dest = memnew_placement(r_dest, String); + dest->append_utf16((const char16_t *)p_contents, p_char_count); } else { - // wchar_t is 32 bit, copy. - memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count)); + // wchar_t is 32 bit (UTF-32). + String *string = memnew_placement(r_dest, String); + string->append_utf32(Span((const char32_t *)p_contents, p_contents ? _strlen_clipped((const char32_t *)p_contents, p_char_count) : 0)); } } static GDExtensionInt gdextension_string_to_latin1_chars(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length) { String *self = (String *)p_self; - CharString cs = self->ascii(true); + CharString cs = self->latin1(); GDExtensionInt len = cs.length(); if (r_text) { const char *s_text = cs.ptr(); @@ -1040,16 +1052,12 @@ static void gdextension_string_name_new_with_latin1_chars(GDExtensionUninitializ } static void gdextension_string_name_new_with_utf8_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents) { - String tmp; - tmp.parse_utf8(p_contents); - + String tmp = String::utf8(p_contents); memnew_placement(r_dest, StringName(tmp)); } static void gdextension_string_name_new_with_utf8_chars_and_len(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String tmp; - tmp.parse_utf8(p_contents, p_size); - + String tmp = String::utf8(p_contents, p_size); memnew_placement(r_dest, StringName(tmp)); } @@ -1543,11 +1551,8 @@ static void gdextension_placeholder_script_instance_update(GDExtensionScriptInst properties_list.push_back(PropertyInfo::from_dict(d)); } - List keys; - values.get_key_list(&keys); - - for (const Variant &E : keys) { - values_map.insert(E, values[E]); + for (const KeyValue &kv : values) { + values_map.insert(kv.key, kv.value); } placeholder->update(properties_list, values_map); @@ -1572,6 +1577,15 @@ static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExt return script_instance_extension->instance; } +static void gdextension_object_set_script_instance(GDExtensionObjectPtr p_object, GDExtensionScriptInstancePtr p_script_instance) { + ERR_FAIL_NULL(p_object); + + Object *o = (Object *)p_object; + ScriptInstance *script_instance = (ScriptInstanceExtension *)p_script_instance; + + o->set_script_instance(script_instance); +} + #ifndef DISABLE_DEPRECATED static void gdextension_callable_custom_create(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_custom_callable_info) { memnew_placement(r_callable, Callable(memnew(CallableCustomExtension(p_custom_callable_info)))); @@ -1666,7 +1680,10 @@ static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data) #define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name) void gdextension_setup_interface() { +#ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(get_godot_version); +#endif // DISABLE_DEPRECATED + REGISTER_INTERFACE_FUNC(get_godot_version2); REGISTER_INTERFACE_FUNC(mem_alloc); REGISTER_INTERFACE_FUNC(mem_realloc); REGISTER_INTERFACE_FUNC(mem_free); @@ -1809,6 +1826,7 @@ void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(placeholder_script_instance_create); REGISTER_INTERFACE_FUNC(placeholder_script_instance_update); REGISTER_INTERFACE_FUNC(object_get_script_instance); + REGISTER_INTERFACE_FUNC(object_set_script_instance); #ifndef DISABLE_DEPRECATED REGISTER_INTERFACE_FUNC(callable_custom_create); #endif // DISABLE_DEPRECATED diff --git a/engine/core/extension/gdextension_interface.h b/engine/core/extension/gdextension_interface.h index ac0181e0..ecd40c86 100644 --- a/engine/core/extension/gdextension_interface.h +++ b/engine/core/extension/gdextension_interface.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_INTERFACE_H -#define GDEXTENSION_INTERFACE_H +#pragma once /* This is a C class header, you can copy it and use it directly in your own binders. * Together with the JSON file, you should be able to generate any binder. @@ -401,6 +400,9 @@ typedef struct { typedef void *GDExtensionClassLibraryPtr; +/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */ +typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array); + /* Method */ typedef enum { @@ -790,9 +792,22 @@ typedef struct { const char *string; } GDExtensionGodotVersion; +typedef struct { + uint32_t major; + uint32_t minor; + uint32_t patch; + uint32_t hex; // Full version encoded as hexadecimal with one byte (2 hex digits) per number (e.g. for "3.1.12" it would be 0x03010C) + const char *status; // (e.g. "stable", "beta", "rc1", "rc2") + const char *build; // (e.g. "custom_build") + const char *hash; // Full Git commit hash. + uint64_t timestamp; // Git commit date UNIX timestamp in seconds, or 0 if unavailable. + const char *string; // (e.g. "Godot v3.1.4.stable.official.mono") +} GDExtensionGodotVersion2; + /** * @name get_godot_version * @since 4.1 + * @deprecated in Godot 4.5. Use `get_godot_version2` instead. * * Gets the Godot version that the GDExtension was loaded into. * @@ -800,6 +815,16 @@ typedef struct { */ typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_godot_version); +/** + * @name get_godot_version2 + * @since 4.5 + * + * Gets the Godot version that the GDExtension was loaded into. + * + * @param r_godot_version A pointer to the structure to write the version information into. + */ +typedef void (*GDExtensionInterfaceGetGodotVersion2)(GDExtensionGodotVersion2 *r_godot_version); + /* INTERFACE: Memory */ /** @@ -2721,6 +2746,17 @@ typedef void (*GDExtensionInterfacePlaceHolderScriptInstanceUpdate)(GDExtensionS */ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptInstance)(GDExtensionConstObjectPtr p_object, GDExtensionObjectPtr p_language); +/** + * @name object_set_script_instance + * @since 4.5 + * + * Set the script instance data attached to this object. + * + * @param p_object A pointer to the Object. + * @param p_script_instance A pointer to the script instance data to attach to this object. + */ +typedef void (*GDExtensionInterfaceObjectSetScriptInstance)(GDExtensionObjectPtr p_object, GDExtensionScriptInstanceDataPtr p_script_instance); + /* INTERFACE: Callable */ /** @@ -3078,8 +3114,22 @@ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char * */ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size); +/** + * @name editor_register_get_classes_used_callback + * @since 4.5 + * + * Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension. + * + * This is used by the editor to generate a build profile (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"), + * in order to recompile Godot with only the classes used. + * In the provided callback, the GDExtension should provide the list of classes that _may_ be used statically, thus the time of invocation shouldn't matter. + * If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes. + * + * @param p_library A pointer the library received by the GDExtension's entry point function. + * @param p_callback The callback to retrieve the list of classes used. + */ +typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback); + #ifdef __cplusplus } #endif - -#endif // GDEXTENSION_INTERFACE_H diff --git a/engine/core/extension/gdextension_library_loader.cpp b/engine/core/extension/gdextension_library_loader.cpp index 17200916..1d6be752 100644 --- a/engine/core/extension/gdextension_library_loader.cpp +++ b/engine/core/extension/gdextension_library_loader.cpp @@ -307,12 +307,12 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { bool compatible = true; // Check version lexicographically. - if (VERSION_MAJOR != compatibility_minimum[0]) { - compatible = VERSION_MAJOR > compatibility_minimum[0]; - } else if (VERSION_MINOR != compatibility_minimum[1]) { - compatible = VERSION_MINOR > compatibility_minimum[1]; + if (GODOT_VERSION_MAJOR != compatibility_minimum[0]) { + compatible = GODOT_VERSION_MAJOR > compatibility_minimum[0]; + } else if (GODOT_VERSION_MINOR != compatibility_minimum[1]) { + compatible = GODOT_VERSION_MINOR > compatibility_minimum[1]; } else { - compatible = VERSION_PATCH >= compatibility_minimum[2]; + compatible = GODOT_VERSION_PATCH >= compatibility_minimum[2]; } if (!compatible) { ERR_PRINT(vformat("GDExtension only compatible with Godot version %d.%d.%d or later: %s", compatibility_minimum[0], compatibility_minimum[1], compatibility_minimum[2], p_path)); @@ -334,15 +334,15 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { } compatible = true; - if (VERSION_MAJOR != compatibility_maximum[0]) { - compatible = VERSION_MAJOR < compatibility_maximum[0]; - } else if (VERSION_MINOR != compatibility_maximum[1]) { - compatible = VERSION_MINOR < compatibility_maximum[1]; + if (GODOT_VERSION_MAJOR != compatibility_maximum[0]) { + compatible = GODOT_VERSION_MAJOR < compatibility_maximum[0]; + } else if (GODOT_VERSION_MINOR != compatibility_maximum[1]) { + compatible = GODOT_VERSION_MINOR < compatibility_maximum[1]; } -#if VERSION_PATCH +#if GODOT_VERSION_PATCH // #if check to avoid -Wtype-limits warning when 0. else { - compatible = VERSION_PATCH <= compatibility_maximum[2]; + compatible = GODOT_VERSION_PATCH <= compatibility_maximum[2]; } #endif diff --git a/engine/core/extension/gdextension_library_loader.h b/engine/core/extension/gdextension_library_loader.h index f781611b..75ad0ebe 100644 --- a/engine/core/extension/gdextension_library_loader.h +++ b/engine/core/extension/gdextension_library_loader.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_LIBRARY_LOADER_H -#define GDEXTENSION_LIBRARY_LOADER_H +#pragma once #include @@ -38,6 +37,8 @@ #include "core/os/shared_object.h" class GDExtensionLibraryLoader : public GDExtensionLoader { + GDSOFTCLASS(GDExtensionLibraryLoader, GDExtensionLoader); + friend class GDExtensionManager; friend class GDExtension; @@ -81,5 +82,3 @@ public: Error parse_gdextension_file(const String &p_path); }; - -#endif // GDEXTENSION_LIBRARY_LOADER_H diff --git a/engine/core/extension/gdextension_loader.h b/engine/core/extension/gdextension_loader.h index 22895503..5d212779 100644 --- a/engine/core/extension/gdextension_loader.h +++ b/engine/core/extension/gdextension_loader.h @@ -28,14 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_LOADER_H -#define GDEXTENSION_LOADER_H +#pragma once #include "core/object/ref_counted.h" class GDExtension; class GDExtensionLoader : public RefCounted { + GDSOFTCLASS(GDExtensionLoader, GDExtensionLoader); + public: virtual Error open_library(const String &p_path) = 0; virtual Error initialize(GDExtensionInterfaceGetProcAddress p_get_proc_address, const Ref &p_extension, GDExtensionInitialization *r_initialization) = 0; @@ -44,5 +45,3 @@ public: virtual bool has_library_changed() const = 0; virtual bool library_exists() const = 0; }; - -#endif // GDEXTENSION_LOADER_H diff --git a/engine/core/extension/gdextension_manager.h b/engine/core/extension/gdextension_manager.h index 39a60047..1523c07c 100644 --- a/engine/core/extension/gdextension_manager.h +++ b/engine/core/extension/gdextension_manager.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_MANAGER_H -#define GDEXTENSION_MANAGER_H +#pragma once #include "core/extension/gdextension.h" @@ -92,5 +91,3 @@ public: }; VARIANT_ENUM_CAST(GDExtensionManager::LoadStatus) - -#endif // GDEXTENSION_MANAGER_H diff --git a/engine/core/extension/gdextension_special_compat_hashes.h b/engine/core/extension/gdextension_special_compat_hashes.h index 0d447897..9cfb9208 100644 --- a/engine/core/extension/gdextension_special_compat_hashes.h +++ b/engine/core/extension/gdextension_special_compat_hashes.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GDEXTENSION_SPECIAL_COMPAT_HASHES_H -#define GDEXTENSION_SPECIAL_COMPAT_HASHES_H +#pragma once #ifndef DISABLE_DEPRECATED @@ -58,5 +57,3 @@ public: }; #endif // DISABLE_DEPRECATED - -#endif // GDEXTENSION_SPECIAL_COMPAT_HASHES_H diff --git a/engine/core/extension/make_interface_dumper.py b/engine/core/extension/make_interface_dumper.py index af356882..45f257a3 100644 --- a/engine/core/extension/make_interface_dumper.py +++ b/engine/core/extension/make_interface_dumper.py @@ -1,55 +1,37 @@ -import zlib +import methods def run(target, source, env): - src = str(source[0]) - dst = str(target[0]) - with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g: - buf = f.read() - decomp_size = len(buf) - - # Use maximum zlib compression level to further reduce file size - # (at the cost of initial build times). - buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) - - g.write( - """/* THIS FILE IS GENERATED DO NOT EDIT */ -#ifndef GDEXTENSION_INTERFACE_DUMP_H -#define GDEXTENSION_INTERFACE_DUMP_H + buffer = methods.get_buffer(str(source[0])) + decomp_size = len(buffer) + buffer = methods.compress_buffer(buffer) + with methods.generated_wrapper(str(target[0])) as file: + file.write(f"""\ #ifdef TOOLS_ENABLED #include "core/io/compression.h" #include "core/io/file_access.h" #include "core/string/ustring.h" -""" - ) +inline constexpr int _gdextension_interface_data_compressed_size = {len(buffer)}; +inline constexpr int _gdextension_interface_data_uncompressed_size = {decomp_size}; +inline constexpr unsigned char _gdextension_interface_data_compressed[] = {{ + {methods.format_buffer(buffer, 1)} +}}; - g.write("static const int _gdextension_interface_data_compressed_size = " + str(len(buf)) + ";\n") - g.write("static const int _gdextension_interface_data_uncompressed_size = " + str(decomp_size) + ";\n") - g.write("static const unsigned char _gdextension_interface_data_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + str(buf[i]) + ",\n") - g.write("};\n") - - g.write( - """ -class GDExtensionInterfaceDump { - public: - static void generate_gdextension_interface_file(const String &p_path) { - Ref fa = FileAccess::open(p_path, FileAccess::WRITE); - ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); - Vector data; - data.resize(_gdextension_interface_data_uncompressed_size); - int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE); - ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt."); - fa->store_buffer(data.ptr(), data.size()); - }; -}; +class GDExtensionInterfaceDump {{ + public: + static void generate_gdextension_interface_file(const String &p_path) {{ + Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); + Vector data; + data.resize(_gdextension_interface_data_uncompressed_size); + int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE); + ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt."); + fa->store_buffer(data.ptr(), data.size()); + }}; +}}; #endif // TOOLS_ENABLED - -#endif // GDEXTENSION_INTERFACE_DUMP_H -""" - ) +""") diff --git a/engine/core/extension/make_wrappers.py b/engine/core/extension/make_wrappers.py index 665b6f0f..96936d8c 100644 --- a/engine/core/extension/make_wrappers.py +++ b/engine/core/extension/make_wrappers.py @@ -119,10 +119,7 @@ def generate_ex_version(argcount, const=False, returns=False): def run(target, source, env): max_versions = 12 - txt = """ -#ifndef GDEXTENSION_WRAPPERS_GEN_H -#define GDEXTENSION_WRAPPERS_GEN_H -""" + txt = "#pragma once" for i in range(max_versions + 1): txt += "\n/* Extension Wrapper " + str(i) + " Arguments */\n" @@ -138,7 +135,5 @@ def run(target, source, env): txt += generate_mod_version(i, True, False) txt += generate_mod_version(i, True, True) - txt += "\n#endif\n" - with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/engine/core/input/default_controller_mappings.h b/engine/core/input/default_controller_mappings.h index 34e7d5d8..6d7c807a 100644 --- a/engine/core/input/default_controller_mappings.h +++ b/engine/core/input/default_controller_mappings.h @@ -28,12 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DEFAULT_CONTROLLER_MAPPINGS_H -#define DEFAULT_CONTROLLER_MAPPINGS_H +#pragma once class DefaultControllerMappings { public: static const char *mappings[]; }; - -#endif // DEFAULT_CONTROLLER_MAPPINGS_H diff --git a/engine/core/input/input.cpp b/engine/core/input/input.cpp index f03b9c05..6b9fec6f 100644 --- a/engine/core/input/input.cpp +++ b/engine/core/input/input.cpp @@ -219,7 +219,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, Listpush_back(name.quote()); } } @@ -1594,8 +1594,8 @@ void Input::parse_mapping(const String &p_mapping) { continue; } - String output = entry[idx].get_slice(":", 0).replace(" ", ""); - String input = entry[idx].get_slice(":", 1).replace(" ", ""); + String output = entry[idx].get_slicec(':', 0).remove_char(' '); + String input = entry[idx].get_slicec(':', 1).remove_char(' '); if (output.length() < 1 || input.length() < 2) { continue; } diff --git a/engine/core/input/input.h b/engine/core/input/input.h index bbe185de..8d3b7ae3 100644 --- a/engine/core/input/input.h +++ b/engine/core/input/input.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef INPUT_H -#define INPUT_H +#pragma once #include "core/input/input_event.h" #include "core/object/object.h" @@ -86,7 +85,7 @@ public: typedef void (*EventDispatchFunc)(const Ref &p_event); private: - BitField mouse_button_mask; + BitField mouse_button_mask = MouseButtonMask::NONE; RBSet key_label_pressed; RBSet physical_keys_pressed; @@ -403,5 +402,3 @@ public: VARIANT_ENUM_CAST(Input::MouseMode); VARIANT_ENUM_CAST(Input::CursorShape); - -#endif // INPUT_H diff --git a/engine/core/input/input_builders.py b/engine/core/input/input_builders.py index 3685e726..c63f595f 100644 --- a/engine/core/input/input_builders.py +++ b/engine/core/input/input_builders.py @@ -2,18 +2,22 @@ from collections import OrderedDict +import methods + def make_default_controller_mappings(target, source, env): - dst = str(target[0]) - with open(dst, "w", encoding="utf-8", newline="\n") as g: - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write('#include "core/typedefs.h"\n') - g.write('#include "core/input/default_controller_mappings.h"\n') + with methods.generated_wrapper(str(target[0])) as file: + file.write("""\ +#include "core/input/default_controller_mappings.h" + +#include "core/typedefs.h" + +""") # ensure mappings have a consistent order - platform_mappings: dict = OrderedDict() - for src_path in source: - with open(str(src_path), "r", encoding="utf-8") as f: + platform_mappings = OrderedDict() + for src_path in map(str, source): + with open(src_path, "r", encoding="utf-8") as f: # read mapping file and skip header mapping_file_lines = f.readlines()[2:] @@ -32,28 +36,28 @@ def make_default_controller_mappings(target, source, env): line_parts = line.split(",") guid = line_parts[0] if guid in platform_mappings[current_platform]: - g.write( + file.write( "// WARNING: DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format( src_path, current_platform, platform_mappings[current_platform][guid] ) ) platform_mappings[current_platform][guid] = line - platform_variables = { - "Linux": "#ifdef LINUXBSD_ENABLED", - "Windows": "#ifdef WINDOWS_ENABLED", - "Mac OS X": "#ifdef MACOS_ENABLED", - "Android": "#ifdef ANDROID_ENABLED", - "iOS": "#ifdef IOS_ENABLED", - "Web": "#ifdef WEB_ENABLED", + PLATFORM_VARIABLES = { + "Linux": "LINUXBSD", + "Windows": "WINDOWS", + "Mac OS X": "MACOS", + "Android": "ANDROID", + "iOS": "IOS", + "Web": "WEB", } - g.write("const char* DefaultControllerMappings::mappings[] = {\n") + file.write("const char *DefaultControllerMappings::mappings[] = {\n") for platform, mappings in platform_mappings.items(): - variable = platform_variables[platform] - g.write("{}\n".format(variable)) + variable = PLATFORM_VARIABLES[platform] + file.write(f"#ifdef {variable}_ENABLED\n") for mapping in mappings.values(): - g.write('\t"{}",\n'.format(mapping)) - g.write("#endif\n") + file.write(f'\t"{mapping}",\n') + file.write(f"#endif // {variable}_ENABLED\n") - g.write("\tnullptr\n};\n") + file.write("\tnullptr\n};\n") diff --git a/engine/core/input/input_enums.h b/engine/core/input/input_enums.h index 182a5aab..d4efb3d8 100644 --- a/engine/core/input/input_enums.h +++ b/engine/core/input/input_enums.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef INPUT_ENUMS_H -#define INPUT_ENUMS_H +#pragma once #include "core/error/error_macros.h" @@ -138,4 +137,10 @@ inline MouseButtonMask mouse_button_to_mask(MouseButton button) { return MouseButtonMask(1 << ((int)button - 1)); } -#endif // INPUT_ENUMS_H +constexpr MouseButtonMask operator|(MouseButtonMask p_a, MouseButtonMask p_b) { + return static_cast(static_cast(p_a) | static_cast(p_b)); +} + +constexpr MouseButtonMask &operator|=(MouseButtonMask &p_a, MouseButtonMask p_b) { + return p_a = p_a | p_b; +} diff --git a/engine/core/input/input_event.cpp b/engine/core/input/input_event.cpp index 6e8cdc4b..85c35c05 100644 --- a/engine/core/input/input_event.cpp +++ b/engine/core/input/input_event.cpp @@ -230,7 +230,7 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif } BitField InputEventWithModifiers::get_modifiers_mask() const { - BitField mask; + BitField mask = {}; if (is_ctrl_pressed()) { mask.set_flag(KeyModifierMask::CTRL); } @@ -385,11 +385,11 @@ bool InputEventKey::is_echo() const { } Key InputEventKey::get_keycode_with_modifiers() const { - return keycode | (int64_t)get_modifiers_mask(); + return keycode | get_modifiers_mask(); } Key InputEventKey::get_physical_keycode_with_modifiers() const { - return physical_keycode | (int64_t)get_modifiers_mask(); + return physical_keycode | get_modifiers_mask(); } Key InputEventKey::get_key_label_with_modifiers() const { diff --git a/engine/core/input/input_event.h b/engine/core/input/input_event.h index 19176f74..6e308f6c 100644 --- a/engine/core/input/input_event.h +++ b/engine/core/input/input_event.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef INPUT_EVENT_H -#define INPUT_EVENT_H +#pragma once #include "core/input/input_enums.h" #include "core/io/resource.h" @@ -209,7 +208,7 @@ public: class InputEventMouse : public InputEventWithModifiers { GDCLASS(InputEventMouse, InputEventWithModifiers); - BitField button_mask; + BitField button_mask = MouseButtonMask::NONE; Vector2 pos; Vector2 global_pos; @@ -595,5 +594,3 @@ public: InputEventShortcut(); }; - -#endif // INPUT_EVENT_H diff --git a/engine/core/input/input_map.cpp b/engine/core/input/input_map.cpp index bcd3b63a..ea03c25c 100644 --- a/engine/core/input/input_map.cpp +++ b/engine/core/input/input_map.cpp @@ -47,6 +47,8 @@ void InputMap::_bind_methods() { ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(DEFAULT_DEADZONE)); ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action); + ClassDB::bind_method(D_METHOD("get_action_description", "action"), &InputMap::get_action_description); + ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone); ClassDB::bind_method(D_METHOD("action_get_deadzone", "action"), &InputMap::action_get_deadzone); ClassDB::bind_method(D_METHOD("action_add_event", "action", "event"), &InputMap::action_add_event); @@ -106,7 +108,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis continue; } - String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length()); + String name = pi.name.substr(pi.name.find_char('/') + 1); r_options->push_back(name.quote()); } } @@ -181,6 +183,25 @@ bool InputMap::has_action(const StringName &p_action) const { return input_map.has(p_action); } +String InputMap::get_action_description(const StringName &p_action) const { + ERR_FAIL_COND_V_MSG(!input_map.has(p_action), String(), suggest_actions(p_action)); + + String ret; + const List> &inputs = input_map[p_action].inputs; + for (Ref iek : inputs) { + if (iek.is_valid()) { + if (!ret.is_empty()) { + ret += RTR(" or "); + } + ret += iek->as_text(); + } + } + if (ret.is_empty()) { + ret = RTR("Action has no bound inputs"); + } + return ret; +} + float InputMap::action_get_deadzone(const StringName &p_action) { ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, suggest_actions(p_action)); @@ -304,7 +325,7 @@ void InputMap::load_from_project_settings() { continue; } - String name = pi.name.substr(pi.name.find_char('/') + 1, pi.name.length()); + String name = pi.name.substr(pi.name.find_char('/') + 1); Dictionary action = GLOBAL_GET(pi.name); float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE; @@ -344,6 +365,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_cut", TTRC("Cut") }, { "ui_copy", TTRC("Copy") }, { "ui_paste", TTRC("Paste") }, + { "ui_focus_mode", TTRC("Toggle Tab Focus Mode") }, { "ui_undo", TTRC("Undo") }, { "ui_redo", TTRC("Redo") }, { "ui_text_completion_query", TTRC("Completion Query") }, @@ -397,17 +419,21 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_text_submit", TTRC("Submit Text") }, { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, { "ui_graph_delete", TTRC("Delete Nodes") }, + { "ui_graph_follow_left", TTRC("Follow Input Port Connection") }, + { "ui_graph_follow_right", TTRC("Follow Output Port Connection") }, { "ui_filedialog_up_one_level", TTRC("Go Up One Level") }, { "ui_filedialog_refresh", TTRC("Refresh") }, { "ui_filedialog_show_hidden", TTRC("Show Hidden") }, { "ui_swap_input_direction ", TTRC("Swap Input Direction") }, { "ui_unicode_start", TTRC("Start Unicode Character Input") }, + { "ui_colorpicker_delete_preset", TTRC("Toggle License Notices") }, + { "ui_accessibility_drag_and_drop", TTRC("Accessibility: Keyboard Drag and Drop") }, { "", ""} /* clang-format on */ }; String InputMap::get_builtin_display_name(const String &p_name) const { - int len = sizeof(_builtin_action_display_names) / sizeof(_BuiltinActionDisplayName); + constexpr int len = std::size(_builtin_action_display_names); for (int i = 0; i < len; i++) { if (_builtin_action_display_names[i].name == p_name) { @@ -487,6 +513,9 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::END)); default_builtin_cache.insert("ui_end", inputs); + inputs = List>(); + default_builtin_cache.insert("ui_accessibility_drag_and_drop", inputs); + // ///// UI basic Shortcuts ///// inputs = List>(); @@ -499,6 +528,10 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::CMD_OR_CTRL)); default_builtin_cache.insert("ui_copy", inputs); + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::M | KeyModifierMask::CTRL)); + default_builtin_cache.insert("ui_focus_mode", inputs); + inputs = List>(); inputs.push_back(InputEventKey::create_reference(Key::V | KeyModifierMask::CMD_OR_CTRL)); inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::SHIFT)); @@ -772,6 +805,22 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE)); default_builtin_cache.insert("ui_graph_delete", inputs); + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::CMD_OR_CTRL)); + default_builtin_cache.insert("ui_graph_follow_left", inputs); + + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::ALT)); + default_builtin_cache.insert("ui_graph_follow_left.macos", inputs); + + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::CMD_OR_CTRL)); + default_builtin_cache.insert("ui_graph_follow_right", inputs); + + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::ALT)); + default_builtin_cache.insert("ui_graph_follow_right.macos", inputs); + // ///// UI File Dialog Shortcuts ///// inputs = List>(); inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE)); @@ -789,6 +838,12 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD_OR_CTRL)); default_builtin_cache.insert("ui_swap_input_direction", inputs); + // ///// UI ColorPicker Shortcuts ///// + inputs = List>(); + inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::X)); + inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE)); + default_builtin_cache.insert("ui_colorpicker_delete_preset", inputs); + return default_builtin_cache; } diff --git a/engine/core/input/input_map.h b/engine/core/input/input_map.h index 520c10c4..00bc1550 100644 --- a/engine/core/input/input_map.h +++ b/engine/core/input/input_map.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef INPUT_MAP_H -#define INPUT_MAP_H +#pragma once #include "core/input/input_event.h" #include "core/object/class_db.h" @@ -86,6 +85,8 @@ public: void add_action(const StringName &p_action, float p_deadzone = DEFAULT_DEADZONE); void erase_action(const StringName &p_action); + String get_action_description(const StringName &p_action) const; + float action_get_deadzone(const StringName &p_action); void action_set_deadzone(const StringName &p_action, float p_deadzone); void action_add_event(const StringName &p_action, const Ref &p_event); @@ -116,5 +117,3 @@ public: InputMap(); ~InputMap(); }; - -#endif // INPUT_MAP_H diff --git a/engine/core/input/shortcut.h b/engine/core/input/shortcut.h index 4109e31f..5c054827 100644 --- a/engine/core/input/shortcut.h +++ b/engine/core/input/shortcut.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef SHORTCUT_H -#define SHORTCUT_H +#pragma once #include "core/input/input_event.h" #include "core/io/resource.h" @@ -55,5 +54,3 @@ public: static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2); }; - -#endif // SHORTCUT_H diff --git a/engine/core/io/compression.cpp b/engine/core/io/compression.cpp index 4e4627c4..79f37db1 100644 --- a/engine/core/io/compression.cpp +++ b/engine/core/io/compression.cpp @@ -42,6 +42,12 @@ #include #endif +// Caches for zstd. +static BinaryMutex mutex; +static ZSTD_DCtx *current_zstd_d_ctx = nullptr; +static bool current_zstd_long_distance_matching; +static int current_zstd_window_log_size; + int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_BROTLI: { @@ -187,12 +193,22 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p return total; } break; case MODE_ZSTD: { - ZSTD_DCtx *dctx = ZSTD_createDCtx(); - if (zstd_long_distance_matching) { - ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size); + MutexLock lock(mutex); + + if (!current_zstd_d_ctx || current_zstd_long_distance_matching != zstd_long_distance_matching || current_zstd_window_log_size != zstd_window_log_size) { + if (current_zstd_d_ctx) { + ZSTD_freeDCtx(current_zstd_d_ctx); + } + + current_zstd_d_ctx = ZSTD_createDCtx(); + if (zstd_long_distance_matching) { + ZSTD_DCtx_setParameter(current_zstd_d_ctx, ZSTD_d_windowLogMax, zstd_window_log_size); + } + current_zstd_long_distance_matching = zstd_long_distance_matching; + current_zstd_window_log_size = zstd_window_log_size; } - int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size); - ZSTD_freeDCtx(dctx); + + int ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size); return ret; } break; } diff --git a/engine/core/io/compression.h b/engine/core/io/compression.h index ea56ab8e..08468de9 100644 --- a/engine/core/io/compression.h +++ b/engine/core/io/compression.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef COMPRESSION_H -#define COMPRESSION_H +#pragma once #include "core/templates/vector.h" #include "core/typedefs.h" @@ -56,5 +55,3 @@ public: static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); static int decompress_dynamic(Vector *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode); }; - -#endif // COMPRESSION_H diff --git a/engine/core/io/config_file.h b/engine/core/io/config_file.h index 05b4ed89..01a860be 100644 --- a/engine/core/io/config_file.h +++ b/engine/core/io/config_file.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CONFIG_FILE_H -#define CONFIG_FILE_H +#pragma once #include "core/io/file_access.h" #include "core/object/ref_counted.h" @@ -78,5 +77,3 @@ public: Error save_encrypted(const String &p_path, const Vector &p_key); Error save_encrypted_pass(const String &p_path, const String &p_pass); }; - -#endif // CONFIG_FILE_H diff --git a/engine/core/io/dir_access.cpp b/engine/core/io/dir_access.cpp index 4bdfc5a5..02f270da 100644 --- a/engine/core/io/dir_access.cpp +++ b/engine/core/io/dir_access.cpp @@ -146,7 +146,7 @@ Error DirAccess::make_dir_recursive(const String &p_dir) { full_dir = p_dir; } - full_dir = full_dir.replace("\\", "/"); + full_dir = full_dir.replace_char('\\', '/'); String base; @@ -336,7 +336,7 @@ Ref DirAccess::create_temp(const String &p_prefix, bool p_keep, Error uint32_t suffix_i = 0; String path; while (true) { - String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", ""); + String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:"); datetime += itos(Time::get_singleton()->get_ticks_usec()); String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : ""); path = (p_prefix.is_empty() ? "" : p_prefix + "-") + suffix; @@ -626,6 +626,10 @@ bool DirAccess::is_case_sensitive(const String &p_path) const { return true; } +bool DirAccess::is_equivalent(const String &p_path_a, const String &p_path_b) const { + return p_path_a == p_path_b; +} + void DirAccess::_bind_methods() { ClassDB::bind_static_method("DirAccess", D_METHOD("open", "path"), &DirAccess::_open); ClassDB::bind_static_method("DirAccess", D_METHOD("get_open_error"), &DirAccess::get_open_error); @@ -671,6 +675,7 @@ void DirAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("get_include_hidden"), &DirAccess::get_include_hidden); ClassDB::bind_method(D_METHOD("is_case_sensitive", "path"), &DirAccess::is_case_sensitive); + ClassDB::bind_method(D_METHOD("is_equivalent", "path_a", "path_b"), &DirAccess::is_equivalent); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_hidden"), "set_include_hidden", "get_include_hidden"); diff --git a/engine/core/io/dir_access.h b/engine/core/io/dir_access.h index 588e0377..511a414f 100644 --- a/engine/core/io/dir_access.h +++ b/engine/core/io/dir_access.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DIR_ACCESS_H -#define DIR_ACCESS_H +#pragma once #include "core/object/ref_counted.h" #include "core/string/ustring.h" @@ -169,10 +168,9 @@ public: virtual bool is_case_sensitive(const String &p_path) const; virtual bool is_bundle(const String &p_file) const { return false; } + virtual bool is_equivalent(const String &p_path_a, const String &p_path_b) const; public: DirAccess() {} virtual ~DirAccess(); }; - -#endif // DIR_ACCESS_H diff --git a/engine/core/io/dtls_server.h b/engine/core/io/dtls_server.h index 5ffed1ec..e22a0eff 100644 --- a/engine/core/io/dtls_server.h +++ b/engine/core/io/dtls_server.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DTLS_SERVER_H -#define DTLS_SERVER_H +#pragma once #include "core/io/net_socket.h" #include "core/io/packet_peer_dtls.h" @@ -53,5 +52,3 @@ public: DTLSServer() {} }; - -#endif // DTLS_SERVER_H diff --git a/engine/core/io/file_access.cpp b/engine/core/io/file_access.cpp index 7d422bf0..68b85cd1 100644 --- a/engine/core/io/file_access.cpp +++ b/engine/core/io/file_access.cpp @@ -104,7 +104,7 @@ Ref FileAccess::create_temp(int p_mode_flags, const String &p_prefix uint32_t suffix_i = 0; String path; while (true) { - String datetime = Time::get_singleton()->get_datetime_string_from_system().replace("-", "").replace("T", "").replace(":", ""); + String datetime = Time::get_singleton()->get_datetime_string_from_system().remove_chars("-T:"); datetime += itos(Time::get_singleton()->get_ticks_usec()); String suffix = datetime + (suffix_i > 0 ? itos(suffix_i) : ""); path = TEMP_DIR.path_join((p_prefix.is_empty() ? "" : p_prefix + "-") + suffix + (extension.is_empty() ? "" : "." + extension)); @@ -259,7 +259,7 @@ FileAccess::AccessType FileAccess::get_access_type() const { String FileAccess::fix_path(const String &p_path) const { // Helper used by file accesses that use a single filesystem. - String r_path = p_path.replace("\\", "/"); + String r_path = p_path.replace_char('\\', '/'); switch (_access_type) { case ACCESS_RESOURCES: { @@ -313,9 +313,15 @@ uint16_t FileAccess::get_16() const { uint16_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint16_t)); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + data = BSWAP16(data); + } +#else if (big_endian) { data = BSWAP16(data); } +#endif return data; } @@ -324,9 +330,15 @@ uint32_t FileAccess::get_32() const { uint32_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint32_t)); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + data = BSWAP32(data); + } +#else if (big_endian) { data = BSWAP32(data); } +#endif return data; } @@ -335,9 +347,15 @@ uint64_t FileAccess::get_64() const { uint64_t data = 0; get_buffer(reinterpret_cast(&data), sizeof(uint64_t)); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + data = BSWAP64(data); + } +#else if (big_endian) { data = BSWAP64(data); } +#endif return data; } @@ -429,7 +447,7 @@ class CharBuffer { public: _FORCE_INLINE_ CharBuffer() : buffer(stack_buffer), - capacity(sizeof(stack_buffer) / sizeof(char)) { + capacity(std::size(stack_buffer)) { } _FORCE_INLINE_ void push_back(char c) { @@ -565,7 +583,7 @@ String FileAccess::get_as_utf8_string(bool p_skip_cr) const { w[len] = 0; String s; - s.parse_utf8((const char *)w, len, p_skip_cr); + s.append_utf8((const char *)w, len, p_skip_cr); return s; } @@ -574,25 +592,43 @@ bool FileAccess::store_8(uint8_t p_dest) { } bool FileAccess::store_16(uint16_t p_dest) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_dest = BSWAP16(p_dest); + } +#else if (big_endian) { p_dest = BSWAP16(p_dest); } +#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint16_t)); } bool FileAccess::store_32(uint32_t p_dest) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_dest = BSWAP32(p_dest); + } +#else if (big_endian) { p_dest = BSWAP32(p_dest); } +#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint32_t)); } bool FileAccess::store_64(uint64_t p_dest) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_dest = BSWAP64(p_dest); + } +#else if (big_endian) { p_dest = BSWAP64(p_dest); } +#endif return store_buffer(reinterpret_cast(&p_dest), sizeof(uint64_t)); } @@ -629,8 +665,29 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { Ref fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file)); - uint64_t mt = fa->_get_modified_time(p_file); - return mt; + return fa->_get_modified_time(p_file); +} + +uint64_t FileAccess::get_access_time(const String &p_file) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return 0; + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'."); + + return fa->_get_access_time(p_file); +} + +int64_t FileAccess::get_size(const String &p_file) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return PackedData::get_singleton()->get_size(p_file); + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), -1, "Cannot create FileAccess for path '" + p_file + "'."); + + return fa->_get_size(p_file); } BitField FileAccess::get_unix_permissions(const String &p_file) { @@ -723,9 +780,7 @@ String FileAccess::get_pascal_string() { get_buffer((uint8_t *)cs.ptr(), sl); cs[sl] = 0; - String ret; - ret.parse_utf8(cs.ptr(), sl); - return ret; + return String::utf8(cs.ptr(), sl); } bool FileAccess::store_line(const String &p_line) { @@ -817,7 +872,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) { } String ret; - ret.parse_utf8((const char *)array.ptr(), array.size()); + ret.append_utf8((const char *)array.ptr(), array.size()); return ret; } @@ -931,7 +986,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float"), &FileAccess::get_float); ClassDB::bind_method(D_METHOD("get_double"), &FileAccess::get_double); ClassDB::bind_method(D_METHOD("get_real"), &FileAccess::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector(FileAccess::*)(int64_t) const) & FileAccess::get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector (FileAccess::*)(int64_t) const) & FileAccess::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &FileAccess::get_line); ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &FileAccess::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text", "skip_cr"), &FileAccess::get_as_text, DEFVAL(false)); @@ -950,7 +1005,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("store_float", "value"), &FileAccess::store_float); ClassDB::bind_method(D_METHOD("store_double", "value"), &FileAccess::store_double); ClassDB::bind_method(D_METHOD("store_real", "value"), &FileAccess::store_real); - ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool(FileAccess::*)(const Vector &)) & FileAccess::store_buffer); + ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (bool (FileAccess::*)(const Vector &))&FileAccess::store_buffer); ClassDB::bind_method(D_METHOD("store_line", "line"), &FileAccess::store_line); ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &FileAccess::store_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("store_string", "string"), &FileAccess::store_string); @@ -963,6 +1018,8 @@ void FileAccess::_bind_methods() { ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists); ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time); + ClassDB::bind_static_method("FileAccess", D_METHOD("get_access_time", "file"), &FileAccess::get_access_time); + ClassDB::bind_static_method("FileAccess", D_METHOD("get_size", "file"), &FileAccess::get_size); ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions); ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions); diff --git a/engine/core/io/file_access.h b/engine/core/io/file_access.h index f53f1f18..1947da85 100644 --- a/engine/core/io/file_access.h +++ b/engine/core/io/file_access.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_H -#define FILE_ACCESS_H +#pragma once #include "core/io/compression.h" #include "core/math/math_defs.h" @@ -87,7 +86,11 @@ public: typedef void (*FileCloseFailNotify)(const String &); typedef Ref (*CreateFunc)(); +#ifdef BIG_ENDIAN_ENABLED + bool big_endian = true; +#else bool big_endian = false; +#endif bool real_is_double = false; virtual BitField _get_unix_permissions(const String &p_file) = 0; @@ -105,6 +108,8 @@ protected: virtual String fix_path(const String &p_path) const; virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file virtual uint64_t _get_modified_time(const String &p_file) = 0; + virtual uint64_t _get_access_time(const String &p_file) = 0; + virtual int64_t _get_size(const String &p_file) = 0; virtual void _set_access_type(AccessType p_access); static FileCloseFailNotify close_fail_notify; @@ -239,6 +244,8 @@ public: static CreateFunc get_create_func(AccessType p_access); static bool exists(const String &p_name); ///< return true if a file exists static uint64_t get_modified_time(const String &p_file); + static uint64_t get_access_time(const String &p_file); + static int64_t get_size(const String &p_file); static BitField get_unix_permissions(const String &p_file); static Error set_unix_permissions(const String &p_file, BitField p_permissions); @@ -273,5 +280,3 @@ public: VARIANT_ENUM_CAST(FileAccess::CompressionMode); VARIANT_ENUM_CAST(FileAccess::ModeFlags); VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags); - -#endif // FILE_ACCESS_H diff --git a/engine/core/io/file_access_compressed.cpp b/engine/core/io/file_access_compressed.cpp index b7300ded..da313492 100644 --- a/engine/core/io/file_access_compressed.cpp +++ b/engine/core/io/file_access_compressed.cpp @@ -247,7 +247,11 @@ bool FileAccessCompressed::eof_reached() const { } uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const { - ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); + if (p_length == 0) { + return 0; + } + + ERR_FAIL_NULL_V(p_dst, -1); ERR_FAIL_COND_V_MSG(f.is_null(), -1, "File must be opened before use."); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); @@ -256,29 +260,38 @@ uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) con return 0; } - for (uint64_t i = 0; i < p_length; i++) { - p_dst[i] = read_ptr[read_pos]; - read_pos++; - if (read_pos >= read_block_size) { - read_block++; + uint64_t dst_idx = 0; + while (true) { + // Copy over as much of our current block as possible. + const uint32_t copied_bytes_count = MIN(p_length - dst_idx, read_block_size - read_pos); + memcpy(p_dst + dst_idx, read_ptr + read_pos, copied_bytes_count); + dst_idx += copied_bytes_count; + read_pos += copied_bytes_count; - if (read_block < read_block_count) { - //read another block of compressed data - f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); - int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); - ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt."); - read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; - read_pos = 0; - - } else { - read_block--; - at_end = true; - if (i + 1 < p_length) { - read_eof = true; - } - return i + 1; - } + if (dst_idx == p_length) { + // We're done! We read back all that was requested. + return p_length; } + + // We're not done yet; try reading the next block. + read_block++; + + if (read_block >= read_block_count) { + // We're done! We read back the whole file. + read_block--; + at_end = true; + if (dst_idx + 1 < p_length) { + read_eof = true; + } + return dst_idx; + } + + // Read the next block of compressed data. + f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); + int ret = Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); + ERR_FAIL_COND_V_MSG(ret == -1, -1, "Compressed file is corrupt."); + read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; + read_pos = 0; } return p_length; @@ -332,6 +345,22 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) { } } +uint64_t FileAccessCompressed::_get_access_time(const String &p_file) { + if (f.is_valid()) { + return f->get_access_time(p_file); + } else { + return 0; + } +} + +int64_t FileAccessCompressed::_get_size(const String &p_file) { + if (f.is_valid()) { + return f->get_size(p_file); + } else { + return -1; + } +} + BitField FileAccessCompressed::_get_unix_permissions(const String &p_file) { if (f.is_valid()) { return f->_get_unix_permissions(p_file); diff --git a/engine/core/io/file_access_compressed.h b/engine/core/io/file_access_compressed.h index 607a45fc..7c5e6a5f 100644 --- a/engine/core/io/file_access_compressed.h +++ b/engine/core/io/file_access_compressed.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_COMPRESSED_H -#define FILE_ACCESS_COMPRESSED_H +#pragma once #include "core/io/compression.h" #include "core/io/file_access.h" class FileAccessCompressed : public FileAccess { + GDSOFTCLASS(FileAccessCompressed, FileAccess); Compression::Mode cmode = Compression::MODE_ZSTD; bool writing = false; uint64_t write_pos = 0; @@ -94,6 +94,8 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint64_t _get_access_time(const String &p_file) override; + virtual int64_t _get_size(const String &p_file) override; virtual BitField _get_unix_permissions(const String &p_file) override; virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; @@ -107,5 +109,3 @@ public: FileAccessCompressed() {} virtual ~FileAccessCompressed(); }; - -#endif // FILE_ACCESS_COMPRESSED_H diff --git a/engine/core/io/file_access_encrypted.cpp b/engine/core/io/file_access_encrypted.cpp index f2749157..7af7737c 100644 --- a/engine/core/io/file_access_encrypted.cpp +++ b/engine/core/io/file_access_encrypted.cpp @@ -30,9 +30,17 @@ #include "file_access_encrypted.h" -#include "core/crypto/crypto_core.h" #include "core/variant/variant.h" +CryptoCore::RandomGenerator *FileAccessEncrypted::_fae_static_rng = nullptr; + +void FileAccessEncrypted::deinitialize() { + if (_fae_static_rng) { + memdelete(_fae_static_rng); + _fae_static_rng = nullptr; + } +} + Error FileAccessEncrypted::open_and_parse(Ref p_base, const Vector &p_key, Mode p_mode, bool p_with_magic, const Vector &p_iv) { ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute())); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); @@ -48,9 +56,15 @@ Error FileAccessEncrypted::open_and_parse(Ref p_base, const Vectorinit() != OK) { + memdelete(_fae_static_rng); + _fae_static_rng = nullptr; + ERR_FAIL_V_MSG(FAILED, "Failed to initialize random number generator."); + } + } + Error err = _fae_static_rng->get_random_bytes(iv.ptrw(), 16); ERR_FAIL_COND_V(err != OK, err); } else { ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER); @@ -265,7 +279,27 @@ bool FileAccessEncrypted::file_exists(const String &p_name) { } uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) { - return 0; + if (file.is_valid()) { + return file->get_modified_time(p_file); + } else { + return 0; + } +} + +uint64_t FileAccessEncrypted::_get_access_time(const String &p_file) { + if (file.is_valid()) { + return file->get_access_time(p_file); + } else { + return 0; + } +} + +int64_t FileAccessEncrypted::_get_size(const String &p_file) { + if (file.is_valid()) { + return file->get_size(p_file); + } else { + return -1; + } } BitField FileAccessEncrypted::_get_unix_permissions(const String &p_file) { diff --git a/engine/core/io/file_access_encrypted.h b/engine/core/io/file_access_encrypted.h index 570955b7..15cad3a1 100644 --- a/engine/core/io/file_access_encrypted.h +++ b/engine/core/io/file_access_encrypted.h @@ -28,14 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_ENCRYPTED_H -#define FILE_ACCESS_ENCRYPTED_H +#pragma once +#include "core/crypto/crypto_core.h" #include "core/io/file_access.h" #define ENCRYPTED_HEADER_MAGIC 0x43454447 class FileAccessEncrypted : public FileAccess { + GDSOFTCLASS(FileAccessEncrypted, FileAccess); + public: enum Mode : int32_t { MODE_READ, @@ -57,6 +59,8 @@ private: void _close(); + static CryptoCore::RandomGenerator *_fae_static_rng; + public: Error open_and_parse(Ref p_base, const Vector &p_key, Mode p_mode, bool p_with_magic = true, const Vector &p_iv = Vector()); Error open_and_parse_password(Ref p_base, const String &p_key, Mode p_mode); @@ -87,6 +91,8 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; + virtual uint64_t _get_access_time(const String &p_file) override; + virtual int64_t _get_size(const String &p_file) override; virtual BitField _get_unix_permissions(const String &p_file) override; virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; @@ -97,8 +103,8 @@ public: virtual void close() override; + static void deinitialize(); + FileAccessEncrypted() {} ~FileAccessEncrypted(); }; - -#endif // FILE_ACCESS_ENCRYPTED_H diff --git a/engine/core/io/file_access_memory.h b/engine/core/io/file_access_memory.h index 6845cf71..2ff638e9 100644 --- a/engine/core/io/file_access_memory.h +++ b/engine/core/io/file_access_memory.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_MEMORY_H -#define FILE_ACCESS_MEMORY_H +#pragma once #include "core/io/file_access.h" class FileAccessMemory : public FileAccess { + GDSOFTCLASS(FileAccessMemory, FileAccess); uint8_t *data = nullptr; uint64_t length = 0; mutable uint64_t pos = 0; @@ -66,6 +66,9 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint64_t _get_access_time(const String &p_file) override { return 0; } + virtual int64_t _get_size(const String &p_file) override { return -1; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -78,5 +81,3 @@ public: FileAccessMemory() {} }; - -#endif // FILE_ACCESS_MEMORY_H diff --git a/engine/core/io/file_access_pack.cpp b/engine/core/io/file_access_pack.cpp index 3fba2c70..788825f3 100644 --- a/engine/core/io/file_access_pack.cpp +++ b/engine/core/io/file_access_pack.cpp @@ -264,7 +264,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, f->get_32(); // patch number, not used for validation. ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, vformat("Pack version unsupported: %d.", version)); - ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor)); + ERR_FAIL_COND_V_MSG(ver_major > GODOT_VERSION_MAJOR || (ver_major == GODOT_VERSION_MAJOR && ver_minor > GODOT_VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor)); uint32_t pack_flags = f->get_32(); uint64_t file_base = f->get_64(); @@ -306,9 +306,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, f->get_buffer((uint8_t *)cs.ptr(), sl); cs[sl] = 0; - String path; - path.parse_utf8(cs.ptr(), sl); - + String path = String::utf8(cs.ptr(), sl); uint64_t ofs = f->get_64(); uint64_t size = f->get_64(); uint8_t md5[16]; @@ -550,7 +548,7 @@ String DirAccessPack::get_drive(int p_drive) { } PackedData::PackedDir *DirAccessPack::_find_dir(const String &p_dir) { - String nd = p_dir.replace("\\", "/"); + String nd = p_dir.replace_char('\\', '/'); // Special handling since simplify_path() will forbid it if (p_dir == "..") { diff --git a/engine/core/io/file_access_pack.h b/engine/core/io/file_access_pack.h index 0e4e7cd2..9a482db7 100644 --- a/engine/core/io/file_access_pack.h +++ b/engine/core/io/file_access_pack.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_PACK_H -#define FILE_ACCESS_PACK_H +#pragma once #include "core/io/dir_access.h" #include "core/io/file_access.h" @@ -127,6 +126,8 @@ public: _FORCE_INLINE_ Ref try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); + _FORCE_INLINE_ int64_t get_size(const String &p_path); + _FORCE_INLINE_ Ref try_open_directory(const String &p_path); _FORCE_INLINE_ bool has_directory(const String &p_path); @@ -156,6 +157,7 @@ public: }; class FileAccessPack : public FileAccess { + GDSOFTCLASS(FileAccessPack, FileAccess); PackedData::PackedFile pf; mutable uint64_t pos; @@ -165,6 +167,8 @@ class FileAccessPack : public FileAccess { Ref f; virtual Error open_internal(const String &p_path, int p_mode_flags) override; virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint64_t _get_access_time(const String &p_file) override { return 0; } + virtual int64_t _get_size(const String &p_file) override { return -1; } virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -200,6 +204,19 @@ public: FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file); }; +int64_t PackedData::get_size(const String &p_path) { + String simplified_path = p_path.simplify_path(); + PathMD5 pmd5(simplified_path.md5_buffer()); + HashMap::Iterator E = files.find(pmd5); + if (!E) { + return -1; // File not found. + } + if (E->value.offset == 0) { + return -1; // File was erased. + } + return E->value.size; +} + Ref PackedData::try_open_path(const String &p_path) { String simplified_path = p_path.simplify_path().trim_prefix("res://"); PathMD5 pmd5(simplified_path.md5_buffer()); @@ -225,6 +242,7 @@ bool PackedData::has_directory(const String &p_path) { } class DirAccessPack : public DirAccess { + GDSOFTCLASS(DirAccessPack, DirAccess); PackedData::PackedDir *current; List list_dirs; @@ -272,5 +290,3 @@ Ref PackedData::try_open_directory(const String &p_path) { } return da; } - -#endif // FILE_ACCESS_PACK_H diff --git a/engine/core/io/file_access_zip.h b/engine/core/io/file_access_zip.h index a1544fee..e1f4439d 100644 --- a/engine/core/io/file_access_zip.h +++ b/engine/core/io/file_access_zip.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FILE_ACCESS_ZIP_H -#define FILE_ACCESS_ZIP_H +#pragma once #ifdef MINIZIP_ENABLED @@ -74,6 +73,7 @@ public: }; class FileAccessZip : public FileAccess { + GDSOFTCLASS(FileAccessZip, FileAccess); unzFile zfile = nullptr; unz_file_info64 file_info; @@ -102,7 +102,9 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists - virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo + virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } + virtual uint64_t _get_access_time(const String &p_file) override { return 0; } + virtual int64_t _get_size(const String &p_file) override { return -1; } virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } @@ -118,5 +120,3 @@ public: }; #endif // MINIZIP_ENABLED - -#endif // FILE_ACCESS_ZIP_H diff --git a/engine/core/io/http_client.cpp b/engine/core/io/http_client.cpp index b7a324e7..c452faf1 100644 --- a/engine/core/io/http_client.cpp +++ b/engine/core/io/http_client.cpp @@ -70,10 +70,9 @@ Error HTTPClient::_request(Method p_method, const String &p_url, const Vector &kv : p_dict) { + String encoded_key = String(kv.key).uri_encode(); + const Variant &value = kv.value; switch (value.get_type()) { case Variant::ARRAY: { // Repeat the key with every values @@ -118,7 +117,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() { continue; } String key = s.substr(0, sp).strip_edges(); - String value = s.substr(sp + 1, s.length()).strip_edges(); + String value = s.substr(sp + 1).strip_edges(); ret[key] = value; } diff --git a/engine/core/io/http_client.h b/engine/core/io/http_client.h index 59452911..fe2f2df2 100644 --- a/engine/core/io/http_client.h +++ b/engine/core/io/http_client.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef HTTP_CLIENT_H -#define HTTP_CLIENT_H +#pragma once #include "core/crypto/crypto.h" #include "core/io/ip.h" @@ -205,5 +204,3 @@ public: VARIANT_ENUM_CAST(HTTPClient::ResponseCode) VARIANT_ENUM_CAST(HTTPClient::Method); VARIANT_ENUM_CAST(HTTPClient::Status); - -#endif // HTTP_CLIENT_H diff --git a/engine/core/io/http_client_tcp.cpp b/engine/core/io/http_client_tcp.cpp index 3147b59c..f6495585 100644 --- a/engine/core/io/http_client_tcp.cpp +++ b/engine/core/io/http_client_tcp.cpp @@ -50,13 +50,13 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Refis_server(), ERR_INVALID_PARAMETER); @@ -196,7 +196,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector< // Should it add utf8 encoding? } if (add_uagent) { - request += "User-Agent: GodotEngine/" + String(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n"; + request += "User-Agent: GodotEngine/" + String(GODOT_VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")\r\n"; } if (add_accept) { request += "Accept: */*\r\n"; @@ -483,8 +483,7 @@ Error HTTPClientTCP::poll() { (rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) { // End of response, parse. response_str.push_back(0); - String response; - response.parse_utf8((const char *)response_str.ptr(), response_str.size()); + String response = String::utf8((const char *)response_str.ptr(), response_str.size()); Vector responses = response.split("\n"); body_size = -1; chunked = false; @@ -508,11 +507,11 @@ Error HTTPClientTCP::poll() { continue; } if (s.begins_with("content-length:")) { - body_size = s.substr(s.find_char(':') + 1, s.length()).strip_edges().to_int(); + body_size = s.substr(s.find_char(':') + 1).strip_edges().to_int(); body_left = body_size; } else if (s.begins_with("transfer-encoding:")) { - String encoding = header.substr(header.find_char(':') + 1, header.length()).strip_edges(); + String encoding = header.substr(header.find_char(':') + 1).strip_edges(); if (encoding == "chunked") { chunked = true; } diff --git a/engine/core/io/http_client_tcp.h b/engine/core/io/http_client_tcp.h index dd6cc6b8..4e4db3ac 100644 --- a/engine/core/io/http_client_tcp.h +++ b/engine/core/io/http_client_tcp.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef HTTP_CLIENT_TCP_H -#define HTTP_CLIENT_TCP_H +#pragma once #include "http_client.h" @@ -100,5 +99,3 @@ public: void set_https_proxy(const String &p_host, int p_port) override; HTTPClientTCP(); }; - -#endif // HTTP_CLIENT_TCP_H diff --git a/engine/core/io/image.cpp b/engine/core/io/image.cpp index 45f9599c..857a9ec6 100644 --- a/engine/core/io/image.cpp +++ b/engine/core/io/image.cpp @@ -31,7 +31,6 @@ #include "image.h" #include "core/config/project_settings.h" -#include "core/error/error_list.h" #include "core/error/error_macros.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -89,11 +88,13 @@ SavePNGFunc Image::save_png_func = nullptr; SaveJPGFunc Image::save_jpg_func = nullptr; SaveEXRFunc Image::save_exr_func = nullptr; SaveWebPFunc Image::save_webp_func = nullptr; +SaveDDSFunc Image::save_dds_func = nullptr; SavePNGBufferFunc Image::save_png_buffer_func = nullptr; SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr; SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr; SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr; +SaveDDSBufferFunc Image::save_dds_buffer_func = nullptr; // External loader function pointers. @@ -105,6 +106,7 @@ ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr; ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_dds_mem_loader_func = nullptr; // External VRAM compression function pointers. @@ -571,7 +573,7 @@ static bool _are_formats_compatible(Image::Format p_format0, Image::Format p_for void Image::convert(Format p_new_format) { ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_new_format)); - if (data.size() == 0 || p_new_format == format) { + if (data.is_empty() || p_new_format == format) { return; } @@ -796,7 +798,7 @@ Image::Format Image::get_format() const { } static double _bicubic_interp_kernel(double x) { - x = ABS(x); + x = Math::abs(x); double bc = 0; @@ -1139,7 +1141,7 @@ bool Image::is_size_po2() const { } void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats."); int w = next_power_of_2(width); int h = next_power_of_2(height); @@ -1158,7 +1160,7 @@ void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { ERR_FAIL_COND_MSG(data.is_empty(), "Cannot resize image before creating it, use set_data() first."); - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats."); bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */; @@ -1461,8 +1463,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot crop in compressed or custom image formats."); - + ERR_FAIL_COND_MSG(is_compressed(), "Cannot crop in compressed image formats."); ERR_FAIL_COND_MSG(p_x < 0, "Start x position cannot be smaller than 0."); ERR_FAIL_COND_MSG(p_y < 0, "Start y position cannot be smaller than 0."); ERR_FAIL_COND_MSG(p_width <= 0, "Width of image must be greater than 0."); @@ -1515,7 +1516,7 @@ void Image::crop(int p_width, int p_height) { } void Image::rotate_90(ClockDirection p_direction) { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats."); ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); @@ -1633,7 +1634,7 @@ void Image::rotate_90(ClockDirection p_direction) { } void Image::rotate_180() { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot rotate in compressed image formats."); ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); @@ -1667,7 +1668,7 @@ void Image::rotate_180() { } void Image::flip_y() { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_y in compressed image formats."); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -1697,7 +1698,7 @@ void Image::flip_y() { } void Image::flip_x() { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot flip_x in compressed image formats."); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -1789,10 +1790,6 @@ int64_t Image::_get_dst_image_size(int p_width, int p_height, Format p_format, i return size; } -bool Image::_can_modify(Format p_format) const { - return !Image::is_format_compressed(p_format); -} - template @@ -1926,7 +1923,7 @@ void Image::shrink_x2() { memcpy(new_data.ptrw(), data.ptr() + ofs, new_size); } else { // Generate a mipmap and replace the original. - ERR_FAIL_COND(!_can_modify(format)); + ERR_FAIL_COND(is_compressed()); new_data.resize((width / 2) * (height / 2) * get_format_pixel_size(format)); ERR_FAIL_COND(data.is_empty() || new_data.is_empty()); @@ -1963,7 +1960,7 @@ void Image::normalize() { } Error Image::generate_mipmaps(bool p_renormalize) { - ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats."); + ERR_FAIL_COND_V_MSG(is_compressed(), ERR_UNAVAILABLE, "Cannot generate mipmaps from compressed image formats."); ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format."); ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0."); @@ -2180,7 +2177,7 @@ void Image::clear_mipmaps() { } bool Image::is_empty() const { - return (data.size() == 0); + return (data.is_empty()); } Vector Image::get_data() const { @@ -2297,7 +2294,7 @@ void Image::initialize_data(const char **p_xpm) { switch (status) { case READING_HEADER: { String line_str = line_ptr; - line_str.replace("\t", " "); + line_str.replace_char('\t', ' '); size_width = line_str.get_slicec(' ', 0).to_int(); size_height = line_str.get_slicec(' ', 1).to_int(); @@ -2441,47 +2438,75 @@ void Image::initialize_data(const char **p_xpm) { } bool Image::is_invisible() const { - if (format == FORMAT_L8 || format == FORMAT_RGB8 || format == FORMAT_RG8) { - return false; - } - - int64_t len = data.size(); + int w, h; + int64_t len; + _get_mipmap_offset_and_size(1, len, w, h); if (len == 0) { return true; } - int w, h; - _get_mipmap_offset_and_size(1, len, w, h); - - const uint8_t *r = data.ptr(); - const unsigned char *data_ptr = r; - - bool detected = false; - switch (format) { case FORMAT_LA8: { - for (int i = 0; i < (len >> 1); i++) { - DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]); - } + const int pixel_count = len / 2; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0xFF00) != 0) { + return false; + } + } } break; case FORMAT_RGBA8: { - for (int i = 0; i < (len >> 2); i++) { - DETECT_NON_ALPHA(data_ptr[(i << 2) + 3]) + const int pixel_count = len / 4; + const uint32_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0xFF000000) != 0) { + return false; + } } - } break; + case FORMAT_RGBA4444: { + const int pixel_count = len / 2; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); - case FORMAT_DXT3: - case FORMAT_DXT5: { - detected = true; + for (int i = 0; i < pixel_count; i++) { + if ((pixeldata[i] & 0x000F) != 0) { + return false; + } + } + } break; + case FORMAT_RGBAH: { + // The alpha mask accounts for the sign bit. + const int pixel_count = len / 4; + const uint16_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i += 4) { + if ((pixeldata[i + 3] & 0x7FFF) != 0) { + return false; + } + } + } break; + case FORMAT_RGBAF: { + // The alpha mask accounts for the sign bit. + const int pixel_count = len / 4; + const uint32_t *pixeldata = reinterpret_cast(data.ptr()); + + for (int i = 0; i < pixel_count; i += 4) { + if ((pixeldata[i + 3] & 0x7FFFFFFF) != 0) { + return false; + } + } } break; default: { + // Formats that are compressed or don't support alpha channels are presumed to be visible. + return false; } } - return !detected; + // Every pixel has been checked, the image is invisible. + return true; } Image::AlphaMode Image::detect_alpha() const { @@ -2603,6 +2628,21 @@ Vector Image::save_exr_to_buffer(bool p_grayscale) const { return save_exr_buffer_func(Ref((Image *)this), p_grayscale); } +Error Image::save_dds(const String &p_path) const { + if (save_dds_func == nullptr) { + return ERR_UNAVAILABLE; + } + + return save_dds_func(p_path, Ref((Image *)this)); +} + +Vector Image::save_dds_to_buffer() const { + if (save_dds_buffer_func == nullptr) { + return Vector(); + } + return save_dds_buffer_func(Ref((Image *)this)); +} + Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_quality) const { if (save_webp_func == nullptr) { return ERR_UNAVAILABLE; @@ -2682,6 +2722,19 @@ Error Image::decompress() { return OK; } +bool Image::can_decompress(const String &p_format_tag) { + if (p_format_tag == "astc") { + return _image_decompress_astc != nullptr; + } else if (p_format_tag == "bptc") { + return _image_decompress_bptc != nullptr; + } else if (p_format_tag == "etc2") { + return _image_decompress_etc2 != nullptr; + } else if (p_format_tag == "s3tc") { + return _image_decompress_bc != nullptr; + } + return false; +} + Error Image::compress(CompressMode p_mode, CompressSource p_source, ASTCFormat p_astc_format) { ERR_FAIL_INDEX_V_MSG(p_mode, COMPRESS_MAX, ERR_INVALID_PARAMETER, "Invalid compress mode."); ERR_FAIL_INDEX_V_MSG(p_source, COMPRESS_SOURCE_MAX, ERR_INVALID_PARAMETER, "Invalid compress source."); @@ -2863,7 +2916,7 @@ void Image::blit_rect(const Ref &p_src, const Rect2i &p_src_rect, const P ERR_FAIL_COND(dsize == 0); ERR_FAIL_COND(srcdsize == 0); ERR_FAIL_COND(format != p_src->format); - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot blit_rect in compressed image formats."); Rect2i src_rect; Rect2i dest_rect; @@ -3043,10 +3096,10 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s } void Image::fill(const Color &p_color) { - if (data.size() == 0) { + if (data.is_empty()) { return; } - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill in compressed image formats."); uint8_t *dst_data_ptr = data.ptrw(); @@ -3059,10 +3112,10 @@ void Image::fill(const Color &p_color) { } void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) { - if (data.size() == 0) { + if (data.is_empty()) { return; } - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot fill rect in compressed image formats."); Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs()); if (!r.has_area()) { @@ -3278,7 +3331,7 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color) uint16_t rgba = 0; rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)); - rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 33)) << 5; + rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 63)) << 5; rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 11; ((uint16_t *)ptr)[ofs] = rgba; @@ -3366,7 +3419,7 @@ int64_t Image::get_data_size() const { } void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) { - ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot adjust_bcs in compressed or custom image formats."); + ERR_FAIL_COND_MSG(is_compressed(), "Cannot adjust_bcs in compressed image formats."); uint8_t *w = data.ptrw(); uint32_t pixel_size = get_format_pixel_size(format); @@ -3524,6 +3577,9 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("save_jpg_to_buffer", "quality"), &Image::save_jpg_to_buffer, DEFVAL(0.75)); ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false)); ClassDB::bind_method(D_METHOD("save_exr_to_buffer", "grayscale"), &Image::save_exr_to_buffer, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("save_dds", "path"), &Image::save_dds); + ClassDB::bind_method(D_METHOD("save_dds_to_buffer"), &Image::save_dds_to_buffer); + ClassDB::bind_method(D_METHOD("save_webp", "path", "lossy", "quality"), &Image::save_webp, DEFVAL(false), DEFVAL(0.75f)); ClassDB::bind_method(D_METHOD("save_webp_to_buffer", "lossy", "quality"), &Image::save_webp_to_buffer, DEFVAL(false), DEFVAL(0.75f)); @@ -3577,6 +3633,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer); ClassDB::bind_method(D_METHOD("load_bmp_from_buffer", "buffer"), &Image::load_bmp_from_buffer); ClassDB::bind_method(D_METHOD("load_ktx_from_buffer", "buffer"), &Image::load_ktx_from_buffer); + ClassDB::bind_method(D_METHOD("load_dds_from_buffer", "buffer"), &Image::load_dds_from_buffer); ClassDB::bind_method(D_METHOD("load_svg_from_buffer", "buffer", "scale"), &Image::load_svg_from_buffer, DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("load_svg_from_string", "svg_str", "scale"), &Image::load_svg_from_string, DEFVAL(1.0)); @@ -3677,7 +3734,7 @@ void Image::normal_map_to_xy() { } Ref Image::rgbe_to_srgb() { - if (data.size() == 0) { + if (data.is_empty()) { return Ref(); } @@ -3724,7 +3781,7 @@ Ref Image::get_image_from_mipmap(int p_mipmap) const { } void Image::bump_map_to_normal_map(float bump_scale) { - ERR_FAIL_COND(!_can_modify(format)); + ERR_FAIL_COND(is_compressed()); clear_mipmaps(); convert(Image::FORMAT_RF); @@ -3799,7 +3856,7 @@ bool Image::detect_signed(bool p_include_mips) const { } void Image::srgb_to_linear() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3830,7 +3887,7 @@ void Image::srgb_to_linear() { } void Image::linear_to_srgb() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3861,7 +3918,7 @@ void Image::linear_to_srgb() { } void Image::premultiply_alpha() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -3883,7 +3940,7 @@ void Image::premultiply_alpha() { } void Image::fix_alpha_edges() { - if (data.size() == 0) { + if (data.is_empty()) { return; } @@ -4072,6 +4129,14 @@ Error Image::load_bmp_from_buffer(const Vector &p_array) { return _load_from_buffer(p_array, _bmp_mem_loader_func); } +Error Image::load_dds_from_buffer(const Vector &p_array) { + ERR_FAIL_NULL_V_MSG( + _dds_mem_loader_func, + ERR_UNAVAILABLE, + "The DDS module isn't enabled. Recompile the Godot editor or export template binary with the `module_dds_enabled=yes` SCons option."); + return _load_from_buffer(p_array, _dds_mem_loader_func); +} + Error Image::load_svg_from_buffer(const Vector &p_array, float scale) { ERR_FAIL_NULL_V_MSG( _svg_scalable_mem_loader_func, @@ -4266,10 +4331,10 @@ Dictionary Image::compute_image_metrics(const Ref p_compared_image, bool // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Dictionary result; - result["max"] = INFINITY; - result["mean"] = INFINITY; - result["mean_squared"] = INFINITY; - result["root_mean_squared"] = INFINITY; + result["max"] = Math::INF; + result["mean"] = Math::INF; + result["mean_squared"] = Math::INF; + result["root_mean_squared"] = Math::INF; result["peak_snr"] = 0.0f; ERR_FAIL_COND_V(p_compared_image.is_null(), result); diff --git a/engine/core/io/image.h b/engine/core/io/image.h index 992c4359..3cb57a3a 100644 --- a/engine/core/io/image.h +++ b/engine/core/io/image.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef IMAGE_H -#define IMAGE_H +#pragma once #include "core/io/resource.h" #include "core/math/color.h" @@ -59,6 +58,9 @@ typedef Vector (*SaveWebPBufferFunc)(const Ref &p_img, const boo typedef Error (*SaveEXRFunc)(const String &p_path, const Ref &p_img, bool p_grayscale); typedef Vector (*SaveEXRBufferFunc)(const Ref &p_img, bool p_grayscale); +typedef Error (*SaveDDSFunc)(const String &p_path, const Ref &p_img); +typedef Vector (*SaveDDSBufferFunc)(const Ref &p_img); + class Image : public Resource { GDCLASS(Image, Resource); @@ -186,10 +188,12 @@ public: static SaveJPGFunc save_jpg_func; static SaveEXRFunc save_exr_func; static SaveWebPFunc save_webp_func; + static SaveDDSFunc save_dds_func; static SavePNGBufferFunc save_png_buffer_func; static SaveEXRBufferFunc save_exr_buffer_func; static SaveJPGBufferFunc save_jpg_buffer_func; static SaveWebPBufferFunc save_webp_buffer_func; + static SaveDDSBufferFunc save_dds_buffer_func; // External loader function pointers. @@ -201,6 +205,7 @@ public: static ImageMemLoadFunc _bmp_mem_loader_func; static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func; static ImageMemLoadFunc _ktx_mem_loader_func; + static ImageMemLoadFunc _dds_mem_loader_func; // External VRAM compression function pointers. @@ -251,7 +256,6 @@ private: _FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int64_t &r_offset, int &r_width, int &r_height) const; // Get where the mipmap begins in data. static int64_t _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr); - bool _can_modify(Format p_format) const; _FORCE_INLINE_ void _get_clipped_src_and_dest_rects(const Ref &p_src, const Rect2i &p_src_rect, const Point2i &p_dest, Rect2i &r_clipped_src_rect, Rect2i &r_clipped_dest_rect) const; @@ -334,9 +338,11 @@ public: static Ref load_from_file(const String &p_path); Error save_png(const String &p_path) const; Error save_jpg(const String &p_path, float p_quality = 0.75) const; + Error save_dds(const String &p_path) const; Vector save_png_to_buffer() const; Vector save_jpg_to_buffer(float p_quality = 0.75) const; Vector save_exr_to_buffer(bool p_grayscale = false) const; + Vector save_dds_to_buffer() const; Error save_exr(const String &p_path, bool p_grayscale = false) const; Error save_webp(const String &p_path, const bool p_lossy = false, const float p_quality = 0.75f) const; Vector save_webp_to_buffer(const bool p_lossy = false, const float p_quality = 0.75f) const; @@ -373,6 +379,8 @@ public: bool is_compressed() const; static bool is_format_compressed(Format p_format); + static bool can_decompress(const String &p_format_tag); + void fix_alpha_edges(); void premultiply_alpha(); void srgb_to_linear(); @@ -403,6 +411,7 @@ public: Error load_tga_from_buffer(const Vector &p_array); Error load_bmp_from_buffer(const Vector &p_array); Error load_ktx_from_buffer(const Vector &p_array); + Error load_dds_from_buffer(const Vector &p_array); Error load_svg_from_buffer(const Vector &p_array, float scale = 1.0); Error load_svg_from_string(const String &p_svg_str, float scale = 1.0); @@ -442,5 +451,3 @@ VARIANT_ENUM_CAST(Image::UsedChannels) VARIANT_ENUM_CAST(Image::AlphaMode) VARIANT_ENUM_CAST(Image::RoughnessChannel) VARIANT_ENUM_CAST(Image::ASTCFormat) - -#endif // IMAGE_H diff --git a/engine/core/io/image_loader.h b/engine/core/io/image_loader.h index 26af6503..00642da0 100644 --- a/engine/core/io/image_loader.h +++ b/engine/core/io/image_loader.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef IMAGE_LOADER_H -#define IMAGE_LOADER_H +#pragma once #include "core/core_bind.h" #include "core/io/file_access.h" @@ -108,5 +107,3 @@ public: virtual bool handles_type(const String &p_type) const override; virtual String get_resource_type(const String &p_path) const override; }; - -#endif // IMAGE_LOADER_H diff --git a/engine/core/io/ip.h b/engine/core/io/ip.h index 4816d59a..9d23a465 100644 --- a/engine/core/io/ip.h +++ b/engine/core/io/ip.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef IP_H -#define IP_H +#pragma once #include "core/io/ip_address.h" #include "core/os/os.h" @@ -110,5 +109,3 @@ public: VARIANT_ENUM_CAST(IP::Type); VARIANT_ENUM_CAST(IP::ResolverStatus); - -#endif // IP_H diff --git a/engine/core/io/ip_address.cpp b/engine/core/io/ip_address.cpp index f12c896d..78b8a19f 100644 --- a/engine/core/io/ip_address.cpp +++ b/engine/core/io/ip_address.cpp @@ -148,7 +148,7 @@ void IPAddress::_parse_ipv6(const String &p_string) { void IPAddress::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) { String ip; if (p_start != 0) { - ip = p_string.substr(p_start, p_string.length() - p_start); + ip = p_string.substr(p_start); } else { ip = p_string; } diff --git a/engine/core/io/ip_address.h b/engine/core/io/ip_address.h index da7b0f77..114038d9 100644 --- a/engine/core/io/ip_address.h +++ b/engine/core/io/ip_address.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef IP_ADDRESS_H -#define IP_ADDRESS_H +#pragma once #include "core/string/ustring.h" @@ -96,4 +95,6 @@ public: IPAddress() { clear(); } }; -#endif // IP_ADDRESS_H +// Zero-constructing IPAddress initializes field, valid, and wildcard to 0 (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/io/json.cpp b/engine/core/io/json.cpp index 131a7e80..fcb6182f 100644 --- a/engine/core/io/json.cpp +++ b/engine/core/io/json.cpp @@ -122,8 +122,7 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_ ERR_FAIL_COND_V_MSG(p_markers.has(d.id()), "\"{...}\"", "Converting circular structure to JSON."); p_markers.insert(d.id()); - List keys; - d.get_key_list(&keys); + LocalVector keys = d.get_key_list(); if (p_sort_keys) { keys.sort_custom(); @@ -664,201 +663,96 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_ case Variant::VECTOR2: { const Vector2 v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - + Array args = { v.x, v.y }; RETURN_ARGS; } break; case Variant::VECTOR2I: { const Vector2i v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - + Array args = { v.x, v.y }; RETURN_ARGS; } break; case Variant::RECT2: { const Rect2 r = p_variant; - - Array args; - args.push_back(r.position.x); - args.push_back(r.position.y); - args.push_back(r.size.width); - args.push_back(r.size.height); - + Array args = { r.position.x, r.position.y, r.size.width, r.size.height }; RETURN_ARGS; } break; case Variant::RECT2I: { const Rect2i r = p_variant; - - Array args; - args.push_back(r.position.x); - args.push_back(r.position.y); - args.push_back(r.size.width); - args.push_back(r.size.height); - + Array args = { r.position.x, r.position.y, r.size.width, r.size.height }; RETURN_ARGS; } break; case Variant::VECTOR3: { const Vector3 v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - args.push_back(v.z); - + Array args = { v.x, v.y, v.z }; RETURN_ARGS; } break; case Variant::VECTOR3I: { const Vector3i v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - args.push_back(v.z); - + Array args = { v.x, v.y, v.z }; RETURN_ARGS; } break; case Variant::TRANSFORM2D: { const Transform2D t = p_variant; - - Array args; - args.push_back(t[0].x); - args.push_back(t[0].y); - args.push_back(t[1].x); - args.push_back(t[1].y); - args.push_back(t[2].x); - args.push_back(t[2].y); - + Array args = { t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y }; RETURN_ARGS; } break; case Variant::VECTOR4: { const Vector4 v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - args.push_back(v.z); - args.push_back(v.w); - + Array args = { v.x, v.y, v.z, v.w }; RETURN_ARGS; } break; case Variant::VECTOR4I: { const Vector4i v = p_variant; - - Array args; - args.push_back(v.x); - args.push_back(v.y); - args.push_back(v.z); - args.push_back(v.w); - + Array args = { v.x, v.y, v.z, v.w }; RETURN_ARGS; } break; case Variant::PLANE: { const Plane p = p_variant; - - Array args; - args.push_back(p.normal.x); - args.push_back(p.normal.y); - args.push_back(p.normal.z); - args.push_back(p.d); - + Array args = { p.normal.x, p.normal.y, p.normal.z, p.d }; RETURN_ARGS; } break; case Variant::QUATERNION: { const Quaternion q = p_variant; - - Array args; - args.push_back(q.x); - args.push_back(q.y); - args.push_back(q.z); - args.push_back(q.w); - + Array args = { q.x, q.y, q.z, q.w }; RETURN_ARGS; } break; case Variant::AABB: { const AABB aabb = p_variant; - - Array args; - args.push_back(aabb.position.x); - args.push_back(aabb.position.y); - args.push_back(aabb.position.z); - args.push_back(aabb.size.x); - args.push_back(aabb.size.y); - args.push_back(aabb.size.z); - + Array args = { aabb.position.x, aabb.position.y, aabb.position.z, aabb.size.x, aabb.size.y, aabb.size.z }; RETURN_ARGS; } break; case Variant::BASIS: { const Basis b = p_variant; - Array args; - args.push_back(b.get_column(0).x); - args.push_back(b.get_column(0).y); - args.push_back(b.get_column(0).z); - args.push_back(b.get_column(1).x); - args.push_back(b.get_column(1).y); - args.push_back(b.get_column(1).z); - args.push_back(b.get_column(2).x); - args.push_back(b.get_column(2).y); - args.push_back(b.get_column(2).z); + Array args = { b.get_column(0).x, b.get_column(0).y, b.get_column(0).z, + b.get_column(1).x, b.get_column(1).y, b.get_column(1).z, + b.get_column(2).x, b.get_column(2).y, b.get_column(2).z }; RETURN_ARGS; } break; case Variant::TRANSFORM3D: { const Transform3D t = p_variant; - Array args; - args.push_back(t.basis.get_column(0).x); - args.push_back(t.basis.get_column(0).y); - args.push_back(t.basis.get_column(0).z); - args.push_back(t.basis.get_column(1).x); - args.push_back(t.basis.get_column(1).y); - args.push_back(t.basis.get_column(1).z); - args.push_back(t.basis.get_column(2).x); - args.push_back(t.basis.get_column(2).y); - args.push_back(t.basis.get_column(2).z); - args.push_back(t.origin.x); - args.push_back(t.origin.y); - args.push_back(t.origin.z); + Array args = { t.basis.get_column(0).x, t.basis.get_column(0).y, t.basis.get_column(0).z, + t.basis.get_column(1).x, t.basis.get_column(1).y, t.basis.get_column(1).z, + t.basis.get_column(2).x, t.basis.get_column(2).y, t.basis.get_column(2).z, + t.origin.x, t.origin.y, t.origin.z }; RETURN_ARGS; } break; case Variant::PROJECTION: { const Projection p = p_variant; - Array args; - args.push_back(p[0].x); - args.push_back(p[0].y); - args.push_back(p[0].z); - args.push_back(p[0].w); - args.push_back(p[1].x); - args.push_back(p[1].y); - args.push_back(p[1].z); - args.push_back(p[1].w); - args.push_back(p[2].x); - args.push_back(p[2].y); - args.push_back(p[2].z); - args.push_back(p[2].w); - args.push_back(p[3].x); - args.push_back(p[3].y); - args.push_back(p[3].z); - args.push_back(p[3].w); + Array args = { p[0].x, p[0].y, p[0].z, p[0].w, + p[1].x, p[1].y, p[1].z, p[1].w, + p[2].x, p[2].y, p[2].z, p[2].w, + p[3].x, p[3].y, p[3].z, p[3].w }; RETURN_ARGS; } break; case Variant::COLOR: { const Color c = p_variant; - - Array args; - args.push_back(c.r); - args.push_back(c.g); - args.push_back(c.b); - args.push_back(c.a); - + Array args = { c.r, c.g, c.b, c.a }; RETURN_ARGS; } break; @@ -922,12 +816,9 @@ Variant JSON::_from_native(const Variant &p_variant, bool p_full_objects, int p_ ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ret, "Variant is too deep. Bailing."); - List keys; - dict.get_key_list(&keys); - - for (const Variant &key : keys) { - args.push_back(_from_native(key, p_full_objects, p_depth + 1)); - args.push_back(_from_native(dict[key], p_full_objects, p_depth + 1)); + for (const KeyValue &kv : dict) { + args.push_back(_from_native(kv.key, p_full_objects, p_depth + 1)); + args.push_back(_from_native(kv.value, p_full_objects, p_depth + 1)); } return ret; diff --git a/engine/core/io/json.h b/engine/core/io/json.h index 70baf289..9169e578 100644 --- a/engine/core/io/json.h +++ b/engine/core/io/json.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef JSON_H -#define JSON_H +#pragma once #include "core/io/resource.h" #include "core/io/resource_loader.h" @@ -125,5 +124,3 @@ public: virtual void get_recognized_extensions(const Ref &p_resource, List *p_extensions) const override; virtual bool recognize(const Ref &p_resource) const override; }; - -#endif // JSON_H diff --git a/engine/core/io/logger.cpp b/engine/core/io/logger.cpp index 2965a1ea..26fb06eb 100644 --- a/engine/core/io/logger.cpp +++ b/engine/core/io/logger.cpp @@ -36,10 +36,9 @@ #include "core/templates/rb_set.h" #include "modules/modules_enabled.gen.h" // For regex. + #ifdef MODULE_REGEX_ENABLED #include "modules/regex/regex.h" -#else -class RegEx : public RefCounted {}; #endif // MODULE_REGEX_ENABLED #if defined(MINGW_ENABLED) || defined(_MSC_VER) @@ -156,7 +155,7 @@ void RotatedFileLogger::rotate_file() { if (FileAccess::exists(base_path)) { if (max_files > 1) { - String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", "."); + String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace_char(':', '.'); String backup_name = base_path.get_basename() + timestamp; if (!base_path.get_extension().is_empty()) { backup_name += "." + base_path.get_extension(); diff --git a/engine/core/io/logger.h b/engine/core/io/logger.h index e55f73f6..f3d8acad 100644 --- a/engine/core/io/logger.h +++ b/engine/core/io/logger.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef LOGGER_H -#define LOGGER_H +#pragma once #include "core/io/file_access.h" #include "core/string/ustring.h" @@ -109,5 +108,3 @@ public: virtual ~CompositeLogger(); }; - -#endif // LOGGER_H diff --git a/engine/core/io/marshalls.cpp b/engine/core/io/marshalls.cpp index 19efe289..c81aaecc 100644 --- a/engine/core/io/marshalls.cpp +++ b/engine/core/io/marshalls.cpp @@ -107,7 +107,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF); String str; - ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); + ERR_FAIL_COND_V(str.append_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); r_string = str; // Add padding. @@ -1345,7 +1345,7 @@ static Error _encode_container_type(const ContainerType &p_type, uint8_t *&buf, _encode_string(EncodedObjectAsID::get_class_static(), buf, r_len); } } else if (p_type.class_name != StringName()) { - _encode_string(p_full_objects ? p_type.class_name.operator String() : EncodedObjectAsID::get_class_static(), buf, r_len); + _encode_string(p_full_objects ? p_type.class_name : EncodedObjectAsID::get_class_static(), buf, r_len); } else { // No need to check `p_full_objects` since `class_name` should be non-empty for `builtin_type == Variant::OBJECT`. if (buf) { @@ -1849,19 +1849,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } r_len += 4; - List keys; - dict.get_key_list(&keys); - - for (const Variant &key : keys) { + for (const KeyValue &kv : dict) { int len; - Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(kv.key, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { buf += len; } - const Variant *value = dict.getptr(key); + const Variant *value = dict.getptr(kv.key); ERR_FAIL_NULL_V(value, ERR_BUG); err = encode_variant(*value, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); diff --git a/engine/core/io/marshalls.h b/engine/core/io/marshalls.h index 82c760c2..1d057d4d 100644 --- a/engine/core/io/marshalls.h +++ b/engine/core/io/marshalls.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MARSHALLS_H -#define MARSHALLS_H +#pragma once #include "core/math/math_defs.h" #include "core/object/ref_counted.h" @@ -226,5 +225,3 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0); Vector vector3_to_float32_array(const Vector3 *vecs, size_t count); - -#endif // MARSHALLS_H diff --git a/engine/core/io/missing_resource.h b/engine/core/io/missing_resource.h index 4cded5ca..702cd3b3 100644 --- a/engine/core/io/missing_resource.h +++ b/engine/core/io/missing_resource.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MISSING_RESOURCE_H -#define MISSING_RESOURCE_H +#pragma once #include "core/io/resource.h" @@ -61,5 +60,3 @@ public: MissingResource(); }; - -#endif // MISSING_RESOURCE_H diff --git a/engine/core/io/net_socket.h b/engine/core/io/net_socket.h index 49b23575..49671ece 100644 --- a/engine/core/io/net_socket.h +++ b/engine/core/io/net_socket.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef NET_SOCKET_H -#define NET_SOCKET_H +#pragma once #include "core/io/ip.h" #include "core/object/ref_counted.h" @@ -79,5 +78,3 @@ public: virtual ~NetSocket() {} }; - -#endif // NET_SOCKET_H diff --git a/engine/core/io/packed_data_container.cpp b/engine/core/io/packed_data_container.cpp index ca236ce0..222e1679 100644 --- a/engine/core/io/packed_data_container.cpp +++ b/engine/core/io/packed_data_container.cpp @@ -268,14 +268,12 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector &tmpd encode_uint32(TYPE_DICT, &tmpdata.write[pos + 0]); encode_uint32(len, &tmpdata.write[pos + 4]); - List keys; - d.get_key_list(&keys); List sortk; - for (const Variant &key : keys) { + for (const KeyValue &kv : d) { DictKey dk; - dk.hash = key.hash(); - dk.key = key; + dk.hash = kv.key.hash(); + dk.key = kv.key; sortk.push_back(dk); } diff --git a/engine/core/io/packed_data_container.h b/engine/core/io/packed_data_container.h index f4ffa090..8d25d5c9 100644 --- a/engine/core/io/packed_data_container.h +++ b/engine/core/io/packed_data_container.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PACKED_DATA_CONTAINER_H -#define PACKED_DATA_CONTAINER_H +#pragma once #include "core/io/resource.h" @@ -100,5 +99,3 @@ public: PackedDataContainerRef() {} }; - -#endif // PACKED_DATA_CONTAINER_H diff --git a/engine/core/io/packet_peer.h b/engine/core/io/packet_peer.h index 86ebe32c..91d3bc44 100644 --- a/engine/core/io/packet_peer.h +++ b/engine/core/io/packet_peer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PACKET_PEER_H -#define PACKET_PEER_H +#pragma once #include "core/io/stream_peer.h" #include "core/object/class_db.h" @@ -124,5 +123,3 @@ public: int get_output_buffer_max_size() const; PacketPeerStream(); }; - -#endif // PACKET_PEER_H diff --git a/engine/core/io/packet_peer_dtls.h b/engine/core/io/packet_peer_dtls.h index 03d97a59..5de9640d 100644 --- a/engine/core/io/packet_peer_dtls.h +++ b/engine/core/io/packet_peer_dtls.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PACKET_PEER_DTLS_H -#define PACKET_PEER_DTLS_H +#pragma once #include "core/crypto/crypto.h" #include "core/io/packet_peer_udp.h" @@ -64,5 +63,3 @@ public: }; VARIANT_ENUM_CAST(PacketPeerDTLS::Status); - -#endif // PACKET_PEER_DTLS_H diff --git a/engine/core/io/packet_peer_udp.cpp b/engine/core/io/packet_peer_udp.cpp index 3463c41a..91e9934f 100644 --- a/engine/core/io/packet_peer_udp.cpp +++ b/engine/core/io/packet_peer_udp.cpp @@ -105,18 +105,16 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { return ERR_UNAVAILABLE; } -/* Bogus GCC warning here: - * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, - * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: - * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] - * 68 | p_buf[dst++] = read[pos + i]; - * | ~~~~~~~~~~~~~^~~~~~~ - */ -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstringop-overflow=0" -#endif + /* Bogus GCC warning here: + * In member function 'int RingBuffer::read(T*, int, bool) [with T = unsigned char]', + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: + * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] + * 68 | p_buf[dst++] = read[pos + i]; + * | ~~~~~~~~~~~~~^~~~~~~ + */ + GODOT_GCC_WARNING_PUSH + GODOT_GCC_PRAGMA(GCC diagnostic warning "-Wstringop-overflow=0") // Can't "ignore" this for some reason. uint32_t size = 0; uint8_t ipv6[16] = {}; @@ -129,9 +127,7 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { *r_buffer = packet_buffer; r_buffer_size = size; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP return OK; } diff --git a/engine/core/io/packet_peer_udp.h b/engine/core/io/packet_peer_udp.h index c69a138c..1c909860 100644 --- a/engine/core/io/packet_peer_udp.h +++ b/engine/core/io/packet_peer_udp.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PACKET_PEER_UDP_H -#define PACKET_PEER_UDP_H +#pragma once #include "core/io/ip.h" #include "core/io/net_socket.h" @@ -97,5 +96,3 @@ public: PacketPeerUDP(); ~PacketPeerUDP(); }; - -#endif // PACKET_PEER_UDP_H diff --git a/engine/core/io/pck_packer.cpp b/engine/core/io/pck_packer.cpp index c7cfca19..75870f09 100644 --- a/engine/core/io/pck_packer.cpp +++ b/engine/core/io/pck_packer.cpp @@ -91,9 +91,9 @@ Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const Stri file->store_32(PACK_HEADER_MAGIC); file->store_32(PACK_FORMAT_VERSION); - file->store_32(VERSION_MAJOR); - file->store_32(VERSION_MINOR); - file->store_32(VERSION_PATCH); + file->store_32(GODOT_VERSION_MAJOR); + file->store_32(GODOT_VERSION_MINOR); + file->store_32(GODOT_VERSION_PATCH); uint32_t pack_flags = 0; if (enc_dir) { @@ -118,8 +118,7 @@ Error PCKPacker::add_file_removal(const String &p_target_path) { pf.size = 0; pf.removal = true; - pf.md5.resize(16); - pf.md5.fill(0); + pf.md5.resize_zeroed(16); files.push_back(pf); diff --git a/engine/core/io/pck_packer.h b/engine/core/io/pck_packer.h index 043a1dbd..4c386b36 100644 --- a/engine/core/io/pck_packer.h +++ b/engine/core/io/pck_packer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PCK_PACKER_H -#define PCK_PACKER_H +#pragma once #include "core/object/ref_counted.h" @@ -66,5 +65,3 @@ public: PCKPacker() {} }; - -#endif // PCK_PACKER_H diff --git a/engine/core/io/plist.cpp b/engine/core/io/plist.cpp index 30c786ae..b02ca8a7 100644 --- a/engine/core/io/plist.cpp +++ b/engine/core/io/plist.cpp @@ -383,14 +383,16 @@ void PListNode::store_text(String &p_stream, uint8_t p_indent) const { p_stream += String("\t").repeat(p_indent); p_stream += "\n"; p_stream += String("\t").repeat(p_indent); - p_stream += data_string + "\n"; + // Data should be Base64 (i.e. ASCII only). + p_stream += String::ascii(data_string) + "\n"; p_stream += String("\t").repeat(p_indent); p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_DATE: { p_stream += String("\t").repeat(p_indent); p_stream += ""; - p_stream += data_string; + // Data should be ISO 8601 (i.e. ASCII only). + p_stream += String::ascii(data_string); p_stream += "\n"; } break; case PList::PLNodeType::PL_NODE_TYPE_STRING: { @@ -629,7 +631,7 @@ bool PList::load_file(const String &p_filename) { unsigned char magic[8]; fb->get_buffer(magic, 8); - if (String((const char *)magic, 8) == "bplist00") { + if (String::ascii(Span((const char *)magic, 8)) == "bplist00") { fb->seek_end(-26); trailer.offset_size = fb->get_8(); trailer.ref_size = fb->get_8(); @@ -645,10 +647,8 @@ bool PList::load_file(const String &p_filename) { Vector array = FileAccess::get_file_as_bytes(p_filename, &err); ERR_FAIL_COND_V(err != OK, false); - String ret; - ret.parse_utf8((const char *)array.ptr(), array.size()); String err_str; - bool ok = load_string(ret, err_str); + bool ok = load_string(String::utf8((const char *)array.ptr(), array.size()), err_str); ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str); return true; diff --git a/engine/core/io/plist.h b/engine/core/io/plist.h index 7b319906..6d2dcef3 100644 --- a/engine/core/io/plist.h +++ b/engine/core/io/plist.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PLIST_H -#define PLIST_H +#pragma once // Property list file format (application/x-plist) parser, property list ASN-1 serialization. @@ -84,6 +83,8 @@ public: /*************************************************************************/ class PListNode : public RefCounted { + GDSOFTCLASS(PListNode, RefCounted); + static int _asn1_size_len(uint8_t p_len_octets); public: @@ -122,5 +123,3 @@ public: PListNode() {} ~PListNode() {} }; - -#endif // PLIST_H diff --git a/engine/core/io/remote_filesystem_client.h b/engine/core/io/remote_filesystem_client.h index f96c263c..6b4db9b5 100644 --- a/engine/core/io/remote_filesystem_client.h +++ b/engine/core/io/remote_filesystem_client.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef REMOTE_FILESYSTEM_CLIENT_H -#define REMOTE_FILESYSTEM_CLIENT_H +#pragma once #include "core/string/ustring.h" #include "core/templates/hash_set.h" @@ -60,5 +59,3 @@ public: Error synchronize_with_server(const String &p_host, int p_port, const String &p_password, String &r_cache_path); virtual ~RemoteFilesystemClient() {} }; - -#endif // REMOTE_FILESYSTEM_CLIENT_H diff --git a/engine/core/io/resource.cpp b/engine/core/io/resource.cpp index 886ec6f5..fac829d9 100644 --- a/engine/core/io/resource.cpp +++ b/engine/core/io/resource.cpp @@ -32,10 +32,15 @@ #include "core/io/resource_loader.h" #include "core/math/math_funcs.h" +#include "core/math/random_pcg.h" #include "core/os/os.h" #include "scene/main/node.h" //only so casting works void Resource::emit_changed() { + if (emit_changed_state != EMIT_CHANGED_UNBLOCKED) { + emit_changed_state = EMIT_CHANGED_BLOCKED_PENDING_EMIT; + return; + } if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) { ResourceLoader::resource_changed_emit(this); return; @@ -44,6 +49,20 @@ void Resource::emit_changed() { emit_signal(CoreStringName(changed)); } +void Resource::_block_emit_changed() { + if (emit_changed_state == EMIT_CHANGED_UNBLOCKED) { + emit_changed_state = EMIT_CHANGED_BLOCKED; + } +} + +void Resource::_unblock_emit_changed() { + bool emit = (emit_changed_state == EMIT_CHANGED_BLOCKED_PENDING_EMIT); + emit_changed_state = EMIT_CHANGED_UNBLOCKED; + if (emit) { + emit_changed(); + } +} + void Resource::_resource_path_changed() { } @@ -95,7 +114,7 @@ void Resource::set_path_cache(const String &p_path) { GDVIRTUAL_CALL(_set_path_cache, p_path); } -static thread_local RandomPCG unique_id_gen(0, RandomPCG::DEFAULT_INC); +static thread_local RandomPCG unique_id_gen = RandomPCG(0); void Resource::seed_scene_unique_id(uint32_t p_seed) { unique_id_gen.seed(p_seed); @@ -205,6 +224,8 @@ Error Resource::copy_from(const Ref &p_resource) { return ERR_INVALID_PARAMETER; } + _block_emit_changed(); + reset_state(); // May want to reset state. List pi; @@ -220,6 +241,9 @@ Error Resource::copy_from(const Ref &p_resource) { set(E.name, p_resource->get(E.name)); } + + _unblock_emit_changed(); + return OK; } @@ -248,9 +272,7 @@ void Resource::_dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMa } break; case Variant::DICTIONARY: { Dictionary d = r_variant; - List keys; - d.get_key_list(&keys); - for (Variant &k : keys) { + for (Variant &k : d.get_key_list()) { if (k.get_type() == Variant::OBJECT) { // Replace in dictionary key. Ref sr = k; @@ -322,11 +344,9 @@ void Resource::_find_sub_resources(const Variant &p_variant, HashSet keys; - d.get_key_list(&keys); - for (const Variant &k : keys) { - _find_sub_resources(k, p_resources_found); - _find_sub_resources(d[k], p_resources_found); + for (const KeyValue &kv : d) { + _find_sub_resources(kv.key, p_resources_found); + _find_sub_resources(kv.value, p_resources_found); } } break; case Variant::OBJECT: { diff --git a/engine/core/io/resource.h b/engine/core/io/resource.h index ebc82cee..14c08629 100644 --- a/engine/core/io/resource.h +++ b/engine/core/io/resource.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_H -#define RESOURCE_H +#pragma once #include "core/io/resource_uid.h" #include "core/object/class_db.h" @@ -72,6 +71,12 @@ private: String import_path; #endif + enum EmitChangedState { + EMIT_CHANGED_UNBLOCKED, + EMIT_CHANGED_BLOCKED, + EMIT_CHANGED_BLOCKED_PENDING_EMIT, + }; + EmitChangedState emit_changed_state = EMIT_CHANGED_UNBLOCKED; bool local_to_scene = false; friend class SceneState; Node *local_scene = nullptr; @@ -85,6 +90,9 @@ protected: virtual void _resource_path_changed(); static void _bind_methods(); + void _block_emit_changed(); + void _unblock_emit_changed(); + void _set_path(const String &p_path); void _take_over_path(const String &p_path); @@ -179,5 +187,3 @@ public: static void get_cached_resources(List> *p_resources); static int get_cached_resource_count(); }; - -#endif // RESOURCE_H diff --git a/engine/core/io/resource_format_binary.cpp b/engine/core/io/resource_format_binary.cpp index 891510e3..98511f02 100644 --- a/engine/core/io/resource_format_binary.cpp +++ b/engine/core/io/resource_format_binary.cpp @@ -162,9 +162,7 @@ StringName ResourceLoaderBinary::_get_string() { return StringName(); } f->get_buffer((uint8_t *)&str_buf[0], len); - String s; - s.parse_utf8(&str_buf[0], len); - return s; + return String::utf8(&str_buf[0], len); } return string_map[id]; @@ -918,9 +916,7 @@ static String get_ustring(Ref f) { Vector str_buf; str_buf.resize(len); f->get_buffer((uint8_t *)&str_buf[0], len); - String s; - s.parse_utf8(&str_buf[0], len); - return s; + return String::utf8(&str_buf[0], len); } String ResourceLoaderBinary::get_unicode_string() { @@ -932,9 +928,7 @@ String ResourceLoaderBinary::get_unicode_string() { return String(); } f->get_buffer((uint8_t *)&str_buf[0], len); - String s; - s.parse_utf8(&str_buf[0], len); - return s; + return String::utf8(&str_buf[0], len); } void ResourceLoaderBinary::get_classes_used(Ref p_f, HashSet *p_classes) { @@ -1028,10 +1022,10 @@ void ResourceLoaderBinary::open(Ref p_f, bool p_no_resources, bool p print_bl("minor: " + itos(ver_minor)); print_bl("format: " + itos(ver_format)); - if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { f.unref(); ERR_FAIL_MSG(vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); } type = get_unicode_string(); @@ -1155,7 +1149,7 @@ String ResourceLoaderBinary::recognize(Ref p_f) { f->get_32(); // ver_minor uint32_t ver_fmt = f->get_32(); - if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { f.unref(); return ""; } @@ -1196,7 +1190,7 @@ String ResourceLoaderBinary::recognize_script_class(Ref p_f) { f->get_32(); // ver_minor uint32_t ver_fmt = f->get_32(); - if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + if (ver_fmt > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { f.unref(); return ""; } @@ -1348,13 +1342,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons bool use_real64 = f->get_32(); 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_big_endian(big_endian != 0); fw->store_32(use_real64); //use real64 + fw->set_big_endian(big_endian != 0); uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -1392,10 +1383,10 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons return ResourceFormatSaverBinary::singleton->save(res, p_path); } - if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); } // Since we're not actually converting the file contents, leave the version @@ -1876,12 +1867,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref f, const V Dictionary d = p_property; f->store_32(uint32_t(d.size())); - List keys; - d.get_key_list(&keys); - - for (const Variant &E : keys) { - write_variant(f, E, resource_map, external_resources, string_map); - write_variant(f, d[E], resource_map, external_resources, string_map); + for (const KeyValue &kv : d) { + write_variant(f, kv.key, resource_map, external_resources, string_map); + write_variant(f, kv.value, resource_map, external_resources, string_map); } } break; @@ -2086,12 +2074,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant Dictionary d = p_variant; _find_resources(d.get_typed_key_script()); _find_resources(d.get_typed_value_script()); - List keys; - d.get_key_list(&keys); - for (const Variant &E : keys) { - _find_resources(E); - Variant v = d[E]; - _find_resources(v); + for (const KeyValue &kv : d) { + _find_resources(kv.key); + _find_resources(kv.value); } } break; case Variant::NODE_PATH: { @@ -2180,14 +2165,14 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Refstore_32(1); - f->set_big_endian(true); } else { f->store_32(0); } - f->store_32(0); //64 bits file, false for now - f->store_32(VERSION_MAJOR); - f->store_32(VERSION_MINOR); + f->set_big_endian(big_endian); + + f->store_32(GODOT_VERSION_MAJOR); + f->store_32(GODOT_VERSION_MINOR); f->store_32(FORMAT_VERSION); if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) { @@ -2424,13 +2409,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU big_endian = f->get_32(); bool use_real64 = f->get_32(); 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_big_endian(big_endian != 0); fw->store_32(use_real64); //use real64 + fw->set_big_endian(big_endian != 0); uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); @@ -2450,10 +2432,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU return ERR_UNAVAILABLE; } - if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + if (ver_format > FORMAT_VERSION || ver_major > GODOT_VERSION_MAJOR) { ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", - local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); + local_path, ver_format, ver_major, ver_minor, GODOT_VERSION_BRANCH)); } // Since we're not actually converting the file contents, leave the version diff --git a/engine/core/io/resource_format_binary.h b/engine/core/io/resource_format_binary.h index ec8d7ead..dfd2cd6f 100644 --- a/engine/core/io/resource_format_binary.h +++ b/engine/core/io/resource_format_binary.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_FORMAT_BINARY_H -#define RESOURCE_FORMAT_BINARY_H +#pragma once #include "core/io/file_access.h" #include "core/io/resource_loader.h" @@ -189,5 +188,3 @@ public: ResourceFormatSaverBinary(); }; - -#endif // RESOURCE_FORMAT_BINARY_H diff --git a/engine/core/io/resource_importer.cpp b/engine/core/io/resource_importer.cpp index b7a14f2b..81c3deb9 100644 --- a/engine/core/io/resource_importer.cpp +++ b/engine/core/io/resource_importer.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/config_file.h" +#include "core/io/image.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" @@ -41,7 +42,7 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Refget_importer_name() < p_b->get_importer_name(); } -Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { +Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid) const { Error err; Ref f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); @@ -65,7 +66,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy int lines = 0; String error_text; - bool path_found = false; //first match must have priority + bool path_found = false; // First match must have priority. + + String decomp_path; + bool decomp_path_found = false; while (true) { assign = Variant(); next_tag.fields.clear(); @@ -73,6 +77,11 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); if (err == ERR_FILE_EOF) { + if (p_load && !path_found && decomp_path_found) { + print_verbose(vformat("No natively supported texture format found for %s, using decompressable format %s.", p_path, decomp_path)); + r_path_and_type.path = decomp_path; + } + return OK; } else if (err != OK) { ERR_PRINT(vformat("ResourceFormatImporter::load - %s.import:%d error: %s.", p_path, lines, error_text)); @@ -84,12 +93,15 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy String feature = assign.get_slicec('.', 1); if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; - path_found = true; //first match must have priority + path_found = true; // First match must have priority. + } else if (p_load && Image::can_decompress(feature) && !decomp_path_found) { // When loading, check for decompressable formats and use first one found if nothing else is supported. + decomp_path = value; + decomp_path_found = true; // First match must have priority. } } else if (!path_found && assign == "path") { r_path_and_type.path = value; - path_found = true; //first match must have priority + path_found = true; // First match must have priority. } else if (assign == "type") { r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value); } else if (assign == "importer") { @@ -154,7 +166,7 @@ Ref ResourceFormatImporter::load(const String &p_path, const String &p Ref ResourceFormatImporter::load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, true); if (err != OK) { if (r_error) { @@ -244,13 +256,13 @@ Error ResourceFormatImporter::get_import_order_threads_and_importer(const String if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { importer = get_importer_by_name(pat.importer); } } else { - importer = get_importer_by_extension(p_path.get_extension().to_lower()); + importer = get_importer_by_file(p_path); } if (importer.is_valid()) { @@ -268,13 +280,13 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const { if (FileAccess::exists(p_path + ".import")) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { importer = get_importer_by_name(pat.importer); } } else { - importer = get_importer_by_extension(p_path.get_extension().to_lower()); + importer = get_importer_by_file(p_path); } if (importer.is_valid()) { @@ -300,7 +312,7 @@ bool ResourceFormatImporter::handles_type(const String &p_type) const { String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return String(); @@ -354,20 +366,20 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat String ResourceFormatImporter::get_import_group_file(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); return valid ? pat.group_file : String(); } bool ResourceFormatImporter::is_import_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); return valid; } String ResourceFormatImporter::get_resource_type(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return ""; @@ -378,7 +390,7 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return ResourceUID::INVALID_ID; @@ -393,7 +405,7 @@ bool ResourceFormatImporter::has_custom_uid_support() const { Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err == OK) { r_type = pat.type; @@ -410,7 +422,7 @@ Error ResourceFormatImporter::get_resource_import_info(const String &p_path, Str Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return Variant(); @@ -420,7 +432,7 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons } void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *r_classes) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return; @@ -431,7 +443,7 @@ void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *p_dependencies, bool p_add_types) { PathAndType pat; - Error err = _get_path_and_type(p_path, pat); + Error err = _get_path_and_type(p_path, pat, false); if (err != OK) { return; @@ -459,12 +471,12 @@ void ResourceFormatImporter::add_importer(const Ref &p_importe } } -void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List> *r_importers) { +void ResourceFormatImporter::get_importers_for_file(const String &p_file, List> *r_importers) { for (int i = 0; i < importers.size(); i++) { List local_exts; importers[i]->get_recognized_extensions(&local_exts); for (const String &F : local_exts) { - if (p_extension.to_lower() == F) { + if (p_file.right(F.length()).nocasecmp_to(F) == 0) { r_importers->push_back(importers[i]); break; } @@ -478,7 +490,7 @@ void ResourceFormatImporter::get_importers(List> *r_import } } -Ref ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { +Ref ResourceFormatImporter::get_importer_by_file(const String &p_file) const { Ref importer; float priority = 0; @@ -486,9 +498,10 @@ Ref ResourceFormatImporter::get_importer_by_extension(const St List local_exts; importers[i]->get_recognized_extensions(&local_exts); for (const String &F : local_exts) { - if (p_extension.to_lower() == F && importers[i]->get_priority() > priority) { + if (p_file.right(F.length()).nocasecmp_to(F) == 0 && importers[i]->get_priority() > priority) { importer = importers[i]; priority = importers[i]->get_priority(); + break; } } } @@ -503,7 +516,7 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { bool valid = true; PathAndType pat; - _get_path_and_type(p_path, pat, &valid); + _get_path_and_type(p_path, pat, false, &valid); if (!valid) { return false; diff --git a/engine/core/io/resource_importer.h b/engine/core/io/resource_importer.h index 1d00ef3b..ff1baad9 100644 --- a/engine/core/io/resource_importer.h +++ b/engine/core/io/resource_importer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_IMPORTER_H -#define RESOURCE_IMPORTER_H +#pragma once #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -49,7 +48,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { ResourceUID::ID uid = ResourceUID::INVALID_ID; }; - Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const; + Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool p_load, bool *r_valid = nullptr) const; static ResourceFormatImporter *singleton; @@ -90,8 +89,8 @@ public: void remove_importer(const Ref &p_importer) { importers.erase(p_importer); } Ref get_importer_by_name(const String &p_name) const; - Ref get_importer_by_extension(const String &p_extension) const; - void get_importers_for_extension(const String &p_extension, List> *r_importers); + Ref get_importer_by_file(const String &p_file) const; + void get_importers_for_file(const String &p_file, List> *r_importers); void get_importers(List> *r_importers); bool are_import_settings_valid(const String &p_path) const; @@ -166,5 +165,3 @@ class ResourceFormatImporterSaver : public ResourceFormatSaver { public: virtual Error set_uid(const String &p_path, ResourceUID::ID p_uid) override; }; - -#endif // RESOURCE_IMPORTER_H diff --git a/engine/core/io/resource_loader.cpp b/engine/core/io/resource_loader.cpp index 04fd641f..869faa98 100644 --- a/engine/core/io/resource_loader.cpp +++ b/engine/core/io/resource_loader.cpp @@ -61,8 +61,6 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ return ret; } - String extension = p_path.get_extension(); - List extensions; if (p_for_type.is_empty()) { get_recognized_extensions(&extensions); @@ -71,7 +69,8 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ } for (const String &E : extensions) { - if (E.nocasecmp_to(extension) == 0) { + const String ext = !E.begins_with(".") ? "." + E : E; + if (p_path.right(ext.length()).nocasecmp_to(ext) == 0) { return true; } } @@ -264,6 +263,14 @@ void ResourceLoader::LoadToken::clear() { thread_load_tasks.erase(local_path); } local_path.clear(); // Mark as already cleared. + if (task_to_await) { + for (KeyValue &E : thread_load_tasks) { + if (E.value.task_id == task_to_await) { + task_to_await = 0; + break; // Same task is reused by nested loads, do not wait for completion here. + } + } + } } } @@ -322,7 +329,7 @@ Ref ResourceLoader::_load(const String &p_path, const String &p_origin #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - if (ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_path.get_extension()).is_valid()) { + if (ResourceFormatImporter::get_singleton()->get_importer_by_file(p_path).is_valid()) { // The format is known to the editor, but the file hasn't been imported // (otherwise, ResourceFormatImporter would have been found as a suitable loader). found = true; @@ -772,6 +779,10 @@ Ref ResourceLoader::_load_complete(LoadToken &p_load_token, Error *r_e return _load_complete_inner(p_load_token, r_error, thread_load_lock); } +void ResourceLoader::set_is_import_thread(bool p_import_thread) { + import_thread = p_import_thread; +} + Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock> &p_thread_load_lock) { if (r_error) { *r_error = OK; @@ -825,6 +836,12 @@ Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro p_thread_load_lock.temp_relock(); load_task.awaited = true; + // Mark nested loads with the same task id as awaited. + for (KeyValue &E : thread_load_tasks) { + if (E.value.task_id == load_task.task_id) { + E.value.awaited = true; + } + } DEV_ASSERT(load_task.status == THREAD_LOAD_FAILED || load_task.status == THREAD_LOAD_LOADED); } else if (load_task.need_wait) { @@ -886,9 +903,11 @@ Ref ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro MessageQueue::get_main_singleton()->push_callable(callable_mp(rcc.source, &Resource::connect_changed).bind(rcc.callable, rcc.flags)); } } - core_bind::Semaphore done; - MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &core_bind::Semaphore::post).bind(1)); - done.wait(); + if (!import_thread) { // Main thread is blocked by initial resource reimport, do not wait. + CoreBind::Semaphore done; + MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &CoreBind::Semaphore::post).bind(1)); + done.wait(); + } } } } @@ -1339,10 +1358,8 @@ void ResourceLoader::load_translation_remaps() { } Dictionary remaps = GLOBAL_GET("internationalization/locale/translation_remaps"); - List keys; - remaps.get_key_list(&keys); - for (const Variant &E : keys) { - Array langs = remaps[E]; + for (const KeyValue &kv : remaps) { + Array langs = kv.value; Vector lang_remaps; lang_remaps.resize(langs.size()); String *lang_remaps_ptrw = lang_remaps.ptrw(); @@ -1350,7 +1367,7 @@ void ResourceLoader::load_translation_remaps() { *lang_remaps_ptrw++ = lang; } - translation_remaps[String(E)] = lang_remaps; + translation_remaps[String(kv.key)] = lang_remaps; } } @@ -1565,6 +1582,7 @@ bool ResourceLoader::create_missing_resources_if_class_unavailable = false; bool ResourceLoader::abort_on_missing_resource = true; bool ResourceLoader::timestamp_on_load = false; +thread_local bool ResourceLoader::import_thread = false; thread_local int ResourceLoader::load_nesting = 0; thread_local Vector ResourceLoader::load_paths_stack; thread_local HashMap>> ResourceLoader::res_ref_overrides; diff --git a/engine/core/io/resource_loader.h b/engine/core/io/resource_loader.h index 10a82e81..189f000e 100644 --- a/engine/core/io/resource_loader.h +++ b/engine/core/io/resource_loader.h @@ -28,15 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_LOADER_H -#define RESOURCE_LOADER_H +#pragma once #include "core/io/resource.h" #include "core/object/gdvirtual.gen.inc" #include "core/object/worker_thread_pool.h" #include "core/os/thread.h" -namespace core_bind { +namespace CoreBind { class ResourceLoader; } @@ -105,7 +104,7 @@ typedef void (*ResourceLoadedCallback)(Ref p_resource, const String &p class ResourceLoader { friend class LoadToken; - friend class core_bind::ResourceLoader; + friend class CoreBind::ResourceLoader; enum { MAX_LOADERS = 64 @@ -205,6 +204,7 @@ private: static void _run_load_task(void *p_userdata); + static thread_local bool import_thread; static thread_local int load_nesting; static thread_local HashMap>> res_ref_overrides; // Outermost key is nesting level. static thread_local Vector load_paths_stack; @@ -254,6 +254,8 @@ public: static bool is_imported(const String &p_path); static int get_import_order(const String &p_path); + static void set_is_import_thread(bool p_import_thread); + static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; } static bool get_timestamp_on_load() { return timestamp_on_load; } @@ -316,5 +318,3 @@ public: static void initialize(); static void finalize(); }; - -#endif // RESOURCE_LOADER_H diff --git a/engine/core/io/resource_saver.h b/engine/core/io/resource_saver.h index 3e082192..5602a3a4 100644 --- a/engine/core/io/resource_saver.h +++ b/engine/core/io/resource_saver.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_SAVER_H -#define RESOURCE_SAVER_H +#pragma once #include "core/io/resource.h" #include "core/object/gdvirtual.gen.inc" @@ -103,5 +102,3 @@ public: static void add_custom_savers(); static void remove_custom_savers(); }; - -#endif // RESOURCE_SAVER_H diff --git a/engine/core/io/resource_uid.cpp b/engine/core/io/resource_uid.cpp index a73adf9d..ef997f74 100644 --- a/engine/core/io/resource_uid.cpp +++ b/engine/core/io/resource_uid.cpp @@ -35,6 +35,7 @@ #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/resource_loader.h" +#include "core/math/random_pcg.h" // These constants are off by 1, causing the 'z' and '9' characters never to be used. // This cannot be fixed without breaking compatibility; see GH-83843. @@ -46,7 +47,7 @@ String ResourceUID::get_cache_file() { } static constexpr uint8_t uuid_characters[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', '0', '1', '2', '3', '4', '5', '6', '7', '8' }; -static constexpr uint32_t uuid_characters_element_count = (sizeof(uuid_characters) / sizeof(*uuid_characters)); +static constexpr uint32_t uuid_characters_element_count = std::size(uuid_characters); static constexpr uint8_t max_uuid_number_length = 13; // Max 0x7FFFFFFFFFFFFFFF (uid://d4n4ub6itg400) size is 13 characters. String ResourceUID::id_to_text(ID p_id) const { @@ -121,10 +122,31 @@ ResourceUID::ID ResourceUID::create_id() { } } +ResourceUID::ID ResourceUID::create_id_for_path(const String &p_path) { + ID id = INVALID_ID; + RandomPCG rng; + + const String project_name = GLOBAL_GET("application/config/name"); + rng.seed(project_name.hash64() * p_path.hash64() * FileAccess::get_md5(p_path).hash64()); + + while (true) { + int64_t num1 = rng.rand(); + int64_t num2 = ((int64_t)rng.rand()) << 32; + id = (num1 | num2) & 0x7FFFFFFFFFFFFFFF; + + MutexLock lock(mutex); + if (!unique_ids.has(id)) { + break; + } + } + return id; +} + bool ResourceUID::has_id(ID p_id) const { MutexLock l(mutex); return unique_ids.has(p_id); } + void ResourceUID::add_id(ID p_id, const String &p_path) { MutexLock l(mutex); ERR_FAIL_COND(unique_ids.has(p_id)); @@ -311,7 +333,7 @@ String ResourceUID::get_path_from_cache(Ref &p_cache_file, const Str ERR_FAIL_COND_V(rl != len, String()); if (singleton->id_to_text(id) == p_uid_string) { - return String(cs); + return String::utf8(cs.get_data()); } } return String(); @@ -327,6 +349,7 @@ void ResourceUID::_bind_methods() { ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id); ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id); + ClassDB::bind_method(D_METHOD("create_id_for_path", "path"), &ResourceUID::create_id_for_path); ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id); ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id); diff --git a/engine/core/io/resource_uid.h b/engine/core/io/resource_uid.h index 2912168d..6ac4c9c9 100644 --- a/engine/core/io/resource_uid.h +++ b/engine/core/io/resource_uid.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RESOURCE_UID_H -#define RESOURCE_UID_H +#pragma once #include "core/object/ref_counted.h" #include "core/string/string_name.h" @@ -71,6 +70,7 @@ public: ID text_to_id(const String &p_text) const; ID create_id(); + ID create_id_for_path(const String &p_path); bool has_id(ID p_id) const; void add_id(ID p_id, const String &p_path); void set_id(ID p_id, const String &p_path); @@ -93,5 +93,3 @@ public: ResourceUID(); ~ResourceUID(); }; - -#endif // RESOURCE_UID_H diff --git a/engine/core/io/stream_peer.cpp b/engine/core/io/stream_peer.cpp index bc7ea8a0..2f2c1d30 100644 --- a/engine/core/io/stream_peer.cpp +++ b/engine/core/io/stream_peer.cpp @@ -125,54 +125,90 @@ void StreamPeer::put_8(int8_t p_val) { } void StreamPeer::put_u16(uint16_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP16(p_val); + } +#else if (big_endian) { p_val = BSWAP16(p_val); } +#endif uint8_t buf[2]; encode_uint16(p_val, buf); put_data(buf, 2); } void StreamPeer::put_16(int16_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP16(p_val); + } +#else if (big_endian) { p_val = BSWAP16(p_val); } +#endif uint8_t buf[2]; encode_uint16(p_val, buf); put_data(buf, 2); } void StreamPeer::put_u32(uint32_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP32(p_val); + } +#else if (big_endian) { p_val = BSWAP32(p_val); } +#endif uint8_t buf[4]; encode_uint32(p_val, buf); put_data(buf, 4); } void StreamPeer::put_32(int32_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP32(p_val); + } +#else if (big_endian) { p_val = BSWAP32(p_val); } +#endif uint8_t buf[4]; encode_uint32(p_val, buf); put_data(buf, 4); } void StreamPeer::put_u64(uint64_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP64(p_val); + } +#else if (big_endian) { p_val = BSWAP64(p_val); } +#endif uint8_t buf[8]; encode_uint64(p_val, buf); put_data(buf, 8); } void StreamPeer::put_64(int64_t p_val) { +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + p_val = BSWAP64(p_val); + } +#else if (big_endian) { p_val = BSWAP64(p_val); } +#endif uint8_t buf[8]; encode_uint64(p_val, buf); put_data(buf, 8); @@ -183,9 +219,15 @@ void StreamPeer::put_half(float p_val) { encode_half(p_val, buf); uint16_t *p16 = (uint16_t *)buf; +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + *p16 = BSWAP16(*p16); + } +#else if (big_endian) { *p16 = BSWAP16(*p16); } +#endif put_data(buf, 2); } @@ -194,10 +236,17 @@ void StreamPeer::put_float(float p_val) { uint8_t buf[4]; encode_float(p_val, buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + uint32_t *p32 = (uint32_t *)buf; + *p32 = BSWAP32(*p32); + } +#else if (big_endian) { uint32_t *p32 = (uint32_t *)buf; *p32 = BSWAP32(*p32); } +#endif put_data(buf, 4); } @@ -206,10 +255,17 @@ void StreamPeer::put_double(double p_val) { uint8_t buf[8]; encode_double(p_val, buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + uint64_t *p64 = (uint64_t *)buf; + *p64 = BSWAP64(*p64); + } +#else if (big_endian) { uint64_t *p64 = (uint64_t *)buf; *p64 = BSWAP64(*p64); } +#endif put_data(buf, 8); } @@ -253,9 +309,15 @@ uint16_t StreamPeer::get_u16() { get_data(buf, 2); uint16_t r = decode_uint16(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP16(r); + } +#else if (big_endian) { r = BSWAP16(r); } +#endif return r; } @@ -265,9 +327,15 @@ int16_t StreamPeer::get_16() { get_data(buf, 2); uint16_t r = decode_uint16(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP16(r); + } +#else if (big_endian) { r = BSWAP16(r); } +#endif return int16_t(r); } @@ -277,9 +345,15 @@ uint32_t StreamPeer::get_u32() { get_data(buf, 4); uint32_t r = decode_uint32(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP32(r); + } +#else if (big_endian) { r = BSWAP32(r); } +#endif return r; } @@ -289,9 +363,15 @@ int32_t StreamPeer::get_32() { get_data(buf, 4); uint32_t r = decode_uint32(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP32(r); + } +#else if (big_endian) { r = BSWAP32(r); } +#endif return int32_t(r); } @@ -301,9 +381,15 @@ uint64_t StreamPeer::get_u64() { get_data(buf, 8); uint64_t r = decode_uint64(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP64(r); + } +#else if (big_endian) { r = BSWAP64(r); } +#endif return r; } @@ -313,9 +399,15 @@ int64_t StreamPeer::get_64() { get_data(buf, 8); uint64_t r = decode_uint64(buf); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + r = BSWAP64(r); + } +#else if (big_endian) { r = BSWAP64(r); } +#endif return int64_t(r); } @@ -324,10 +416,17 @@ float StreamPeer::get_half() { uint8_t buf[2]; get_data(buf, 2); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + uint16_t *p16 = (uint16_t *)buf; + *p16 = BSWAP16(*p16); + } +#else if (big_endian) { uint16_t *p16 = (uint16_t *)buf; *p16 = BSWAP16(*p16); } +#endif return decode_half(buf); } @@ -336,10 +435,17 @@ float StreamPeer::get_float() { uint8_t buf[4]; get_data(buf, 4); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + uint32_t *p32 = (uint32_t *)buf; + *p32 = BSWAP32(*p32); + } +#else if (big_endian) { uint32_t *p32 = (uint32_t *)buf; *p32 = BSWAP32(*p32); } +#endif return decode_float(buf); } @@ -348,10 +454,17 @@ double StreamPeer::get_double() { uint8_t buf[8]; get_data(buf, 8); +#ifdef BIG_ENDIAN_ENABLED + if (!big_endian) { + uint64_t *p64 = (uint64_t *)buf; + *p64 = BSWAP64(*p64); + } +#else if (big_endian) { uint64_t *p64 = (uint64_t *)buf; *p64 = BSWAP64(*p64); } +#endif return decode_double(buf); } @@ -383,9 +496,7 @@ String StreamPeer::get_utf8_string(int p_bytes) { err = get_data(buf.ptrw(), p_bytes); ERR_FAIL_COND_V(err != OK, String()); - String ret; - ret.parse_utf8((const char *)buf.ptr(), buf.size()); - return ret; + return String::utf8((const char *)buf.ptr(), buf.size()); } Variant StreamPeer::get_var(bool p_allow_objects) { diff --git a/engine/core/io/stream_peer.h b/engine/core/io/stream_peer.h index 44bbfbf1..a73e92d2 100644 --- a/engine/core/io/stream_peer.h +++ b/engine/core/io/stream_peer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef STREAM_PEER_H -#define STREAM_PEER_H +#pragma once #include "core/object/ref_counted.h" @@ -50,7 +49,11 @@ protected: Array _get_data(int p_bytes); Array _get_partial_data(int p_bytes); +#ifdef BIG_ENDIAN_ENABLED + bool big_endian = true; +#else bool big_endian = false; +#endif public: virtual Error put_data(const uint8_t *p_data, int p_bytes) = 0; ///< put a whole chunk of data, blocking until it sent @@ -152,5 +155,3 @@ public: StreamPeerBuffer() {} }; - -#endif // STREAM_PEER_H diff --git a/engine/core/io/stream_peer_gzip.cpp b/engine/core/io/stream_peer_gzip.cpp index 514bcf59..ed247eaf 100644 --- a/engine/core/io/stream_peer_gzip.cpp +++ b/engine/core/io/stream_peer_gzip.cpp @@ -195,12 +195,12 @@ int StreamPeerGZIP::get_available_bytes() const { Error StreamPeerGZIP::finish() { ERR_FAIL_COND_V(!ctx || !compressing, ERR_UNAVAILABLE); // Ensure we have enough space in temporary buffer. - if (buffer.size() < 1024) { - buffer.resize(1024); // 1024 should be more than enough. + if (buffer.size() < get_available_bytes()) { + buffer.resize(get_available_bytes()); // get_available_bytes() is what we can store in RingBuffer. } int consumed = 0; int to_write = 0; - Error err = _process(buffer.ptrw(), 1024, nullptr, 0, consumed, to_write, true); // compress + Error err = _process(buffer.ptrw(), buffer.size(), nullptr, 0, consumed, to_write, true); // compress if (err != OK) { return err; } diff --git a/engine/core/io/stream_peer_gzip.h b/engine/core/io/stream_peer_gzip.h index a2e25ea4..394fd613 100644 --- a/engine/core/io/stream_peer_gzip.h +++ b/engine/core/io/stream_peer_gzip.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef STREAM_PEER_GZIP_H -#define STREAM_PEER_GZIP_H +#pragma once #include "core/io/stream_peer.h" @@ -72,5 +71,3 @@ public: StreamPeerGZIP(); ~StreamPeerGZIP(); }; - -#endif // STREAM_PEER_GZIP_H diff --git a/engine/core/io/stream_peer_tcp.h b/engine/core/io/stream_peer_tcp.h index d7da7503..80097a66 100644 --- a/engine/core/io/stream_peer_tcp.h +++ b/engine/core/io/stream_peer_tcp.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef STREAM_PEER_TCP_H -#define STREAM_PEER_TCP_H +#pragma once #include "core/io/ip.h" #include "core/io/ip_address.h" @@ -92,5 +91,3 @@ public: }; VARIANT_ENUM_CAST(StreamPeerTCP::Status); - -#endif // STREAM_PEER_TCP_H diff --git a/engine/core/io/stream_peer_tls.h b/engine/core/io/stream_peer_tls.h index 3e03e25a..80a48115 100644 --- a/engine/core/io/stream_peer_tls.h +++ b/engine/core/io/stream_peer_tls.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef STREAM_PEER_TLS_H -#define STREAM_PEER_TLS_H +#pragma once #include "core/crypto/crypto.h" #include "core/io/stream_peer.h" @@ -66,5 +65,3 @@ public: }; VARIANT_ENUM_CAST(StreamPeerTLS::Status); - -#endif // STREAM_PEER_TLS_H diff --git a/engine/core/io/tcp_server.h b/engine/core/io/tcp_server.h index 472d86f3..943d4c6f 100644 --- a/engine/core/io/tcp_server.h +++ b/engine/core/io/tcp_server.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TCP_SERVER_H -#define TCP_SERVER_H +#pragma once #include "core/io/ip.h" #include "core/io/net_socket.h" @@ -59,5 +58,3 @@ public: TCPServer(); ~TCPServer(); }; - -#endif // TCP_SERVER_H diff --git a/engine/core/io/translation_loader_po.cpp b/engine/core/io/translation_loader_po.cpp index 1761d6fa..35773109 100644 --- a/engine/core/io/translation_loader_po.cpp +++ b/engine/core/io/translation_loader_po.cpp @@ -76,14 +76,17 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ bool is_plural = false; for (uint32_t j = 0; j < str_len + 1; j++) { if (data[j] == 0x04) { - msg_context.parse_utf8((const char *)data.ptr(), j); + msg_context.clear(); + msg_context.append_utf8((const char *)data.ptr(), j); str_start = j + 1; } if (data[j] == 0x00) { if (is_plural) { - msg_id_plural.parse_utf8((const char *)(data.ptr() + str_start), j - str_start); + msg_id_plural.clear(); + msg_id_plural.append_utf8((const char *)(data.ptr() + str_start), j - str_start); } else { - msg_id.parse_utf8((const char *)(data.ptr() + str_start), j - str_start); + msg_id.clear(); + msg_id.append_utf8((const char *)(data.ptr() + str_start), j - str_start); is_plural = true; } str_start = j + 1; @@ -189,7 +192,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } } msg_context = ""; - l = l.substr(7, l.length()).strip_edges(); + l = l.substr(7).strip_edges(); status = STATUS_READING_CONTEXT; entered_context = true; } @@ -202,7 +205,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } // We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already. // We just have to reset variables related to plurals for "msgstr[]" later on. - l = l.substr(12, l.length()).strip_edges(); + l = l.substr(12).strip_edges(); plural_index = -1; msgs_plural.clear(); msgs_plural.resize(plural_forms); @@ -230,7 +233,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ } } - l = l.substr(5, l.length()).strip_edges(); + l = l.substr(5).strip_edges(); status = STATUS_READING_ID; // If we did not encounter msgctxt, we reset context to empty to reset it. if (!entered_context) { @@ -246,10 +249,10 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ if (l.begins_with("msgstr[")) { ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref(), vformat("Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: %s:%d.", path, line)); plural_index++; // Increment to add to the next slot in vector msgs_plural. - l = l.substr(9, l.length()).strip_edges(); + l = l.substr(9).strip_edges(); } else if (l.begins_with("msgstr")) { ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref(), vformat("Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: %s:%d.", path, line)); - l = l.substr(6, l.length()).strip_edges(); + l = l.substr(6).strip_edges(); status = STATUS_READING_STRING; } @@ -263,7 +266,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref(), vformat("Invalid line '%s' while parsing: %s:%d.", l, path, line)); - l = l.substr(1, l.length()); + l = l.substr(1); // Find final quote, ignoring escaped ones (\"). // The escape_next logic is necessary to properly parse things like \\" // where the backslash is the one being escaped, not the quote. @@ -329,7 +332,7 @@ Ref TranslationLoaderPO::load_translation(Ref f, Error *r_ continue; } String prop = c.substr(0, p).strip_edges(); - String value = c.substr(p + 1, c.length()).strip_edges(); + String value = c.substr(p + 1).strip_edges(); if (prop == "X-Language" || prop == "Language") { translation->set_locale(value); diff --git a/engine/core/io/translation_loader_po.h b/engine/core/io/translation_loader_po.h index 1f9782c4..5ed0e1f5 100644 --- a/engine/core/io/translation_loader_po.h +++ b/engine/core/io/translation_loader_po.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRANSLATION_LOADER_PO_H -#define TRANSLATION_LOADER_PO_H +#pragma once #include "core/io/file_access.h" #include "core/io/resource_loader.h" @@ -49,5 +48,3 @@ public: TranslationLoaderPO() {} }; - -#endif // TRANSLATION_LOADER_PO_H diff --git a/engine/core/io/udp_server.h b/engine/core/io/udp_server.h index 39b7fd98..9edf4318 100644 --- a/engine/core/io/udp_server.h +++ b/engine/core/io/udp_server.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef UDP_SERVER_H -#define UDP_SERVER_H +#pragma once #include "core/io/net_socket.h" #include "core/io/packet_peer_udp.h" @@ -76,5 +75,3 @@ public: UDPServer(); ~UDPServer(); }; - -#endif // UDP_SERVER_H diff --git a/engine/core/io/xml_parser.cpp b/engine/core/io/xml_parser.cpp index ed1f6f4e..a50a1723 100644 --- a/engine/core/io/xml_parser.cpp +++ b/engine/core/io/xml_parser.cpp @@ -95,7 +95,8 @@ void XMLParser::_ignore_definition() { while (*P && *P != '>') { next_char(); } - node_name.parse_utf8(F, P - F); + node_name.clear(); + node_name.append_utf8(F, P - F); if (*P) { next_char(); diff --git a/engine/core/io/xml_parser.h b/engine/core/io/xml_parser.h index a14bdee5..911d2b11 100644 --- a/engine/core/io/xml_parser.h +++ b/engine/core/io/xml_parser.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef XML_PARSER_H -#define XML_PARSER_H +#pragma once #include "core/object/ref_counted.h" #include "core/string/ustring.h" @@ -126,5 +125,3 @@ public: }; VARIANT_ENUM_CAST(XMLParser::NodeType); - -#endif // XML_PARSER_H diff --git a/engine/core/io/zip_io.cpp b/engine/core/io/zip_io.cpp index 972656e2..e01c181a 100644 --- a/engine/core/io/zip_io.cpp +++ b/engine/core/io/zip_io.cpp @@ -76,8 +76,7 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) { Ref *fa = reinterpret_cast *>(opaque); ERR_FAIL_NULL_V(fa, nullptr); - String fname; - fname.parse_utf8(p_fname); + String fname = String::utf8(p_fname); int file_access_mode = 0; if (mode & ZLIB_FILEFUNC_MODE_READ) { diff --git a/engine/core/io/zip_io.h b/engine/core/io/zip_io.h index cd5c873c..82004d9c 100644 --- a/engine/core/io/zip_io.h +++ b/engine/core/io/zip_io.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef ZIP_IO_H -#define ZIP_IO_H +#pragma once #include "core/io/file_access.h" @@ -61,5 +60,3 @@ voidpf zipio_alloc(voidpf opaque, uInt items, uInt size); void zipio_free(voidpf opaque, voidpf address); zlib_filefunc_def zipio_create_io(Ref *p_data); - -#endif // ZIP_IO_H diff --git a/engine/core/math/a_star.cpp b/engine/core/math/a_star.cpp index 060b1bb1..9b6717c6 100644 --- a/engine/core/math/a_star.cpp +++ b/engine/core/math/a_star.cpp @@ -302,12 +302,7 @@ Vector3 AStar3D::get_closest_position_in_segment(const Vector3 &p_point) const { continue; } - Vector3 segment[2] = { - from_point->pos, - to_point->pos, - }; - - Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, segment); + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, from_point->pos, to_point->pos); real_t d = p_point.distance_squared_to(p); if (d < closest_dist) { closest_point = p; diff --git a/engine/core/math/a_star.h b/engine/core/math/a_star.h index e510923b..d7e0f3fd 100644 --- a/engine/core/math/a_star.h +++ b/engine/core/math/a_star.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef A_STAR_H -#define A_STAR_H +#pragma once #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -222,5 +221,3 @@ public: AStar2D() {} ~AStar2D() {} }; - -#endif // A_STAR_H diff --git a/engine/core/math/a_star_grid_2d.cpp b/engine/core/math/a_star_grid_2d.cpp index 7e0e982c..8bde50ad 100644 --- a/engine/core/math/a_star_grid_2d.cpp +++ b/engine/core/math/a_star_grid_2d.cpp @@ -34,27 +34,27 @@ #include "core/variant/typed_array.h" static real_t heuristic_euclidean(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)ABS(p_to.x - p_from.x); - real_t dy = (real_t)ABS(p_to.y - p_from.y); + real_t dx = (real_t)Math::abs(p_to.x - p_from.x); + real_t dy = (real_t)Math::abs(p_to.y - p_from.y); return (real_t)Math::sqrt(dx * dx + dy * dy); } static real_t heuristic_manhattan(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)ABS(p_to.x - p_from.x); - real_t dy = (real_t)ABS(p_to.y - p_from.y); + real_t dx = (real_t)Math::abs(p_to.x - p_from.x); + real_t dy = (real_t)Math::abs(p_to.y - p_from.y); return dx + dy; } static real_t heuristic_octile(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)ABS(p_to.x - p_from.x); - real_t dy = (real_t)ABS(p_to.y - p_from.y); - real_t F = Math_SQRT2 - 1; + real_t dx = (real_t)Math::abs(p_to.x - p_from.x); + real_t dy = (real_t)Math::abs(p_to.y - p_from.y); + real_t F = Math::SQRT2 - 1; return (dx < dy) ? F * dx + dy : F * dy + dx; } static real_t heuristic_chebyshev(const Vector2i &p_from, const Vector2i &p_to) { - real_t dx = (real_t)ABS(p_to.x - p_from.x); - real_t dy = (real_t)ABS(p_to.y - p_from.y); + real_t dx = (real_t)Math::abs(p_to.x - p_from.x); + real_t dy = (real_t)Math::abs(p_to.y - p_from.y); return MAX(dx, dy); } @@ -503,6 +503,7 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_ LocalVector open_list; SortArray sorter; + LocalVector nbors; p_begin_point->g_score = 0; p_begin_point->f_score = _estimate_cost(p_begin_point->id, p_end_point->id); @@ -528,7 +529,7 @@ bool AStarGrid2D::_solve(Point *p_begin_point, Point *p_end_point, bool p_allow_ open_list.remove_at(open_list.size() - 1); p->closed_pass = pass; // Mark the point as closed. - LocalVector nbors; + nbors.clear(); _get_nbors(p, nbors); for (Point *e : nbors) { diff --git a/engine/core/math/a_star_grid_2d.h b/engine/core/math/a_star_grid_2d.h index ae6f3a1f..4883c092 100644 --- a/engine/core/math/a_star_grid_2d.h +++ b/engine/core/math/a_star_grid_2d.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef A_STAR_GRID_2D_H -#define A_STAR_GRID_2D_H +#pragma once #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -230,5 +229,3 @@ public: VARIANT_ENUM_CAST(AStarGrid2D::DiagonalMode); VARIANT_ENUM_CAST(AStarGrid2D::Heuristic); VARIANT_ENUM_CAST(AStarGrid2D::CellShape) - -#endif // A_STAR_GRID_2D_H diff --git a/engine/core/math/aabb.cpp b/engine/core/math/aabb.cpp index 7d1d7c56..0e01771a 100644 --- a/engine/core/math/aabb.cpp +++ b/engine/core/math/aabb.cpp @@ -37,14 +37,6 @@ real_t AABB::get_volume() const { return size.x * size.y * size.z; } -bool AABB::operator==(const AABB &p_rval) const { - return ((position == p_rval.position) && (size == p_rval.size)); -} - -bool AABB::operator!=(const AABB &p_rval) const { - return ((position != p_rval.position) || (size != p_rval.size)); -} - void AABB::merge_with(const AABB &p_aabb) { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { @@ -76,6 +68,10 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const { return position.is_equal_approx(p_aabb.position) && size.is_equal_approx(p_aabb.size); } +bool AABB::is_same(const AABB &p_aabb) const { + return position.is_same(p_aabb.position) && size.is_same(p_aabb.size); +} + bool AABB::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/engine/core/math/aabb.h b/engine/core/math/aabb.h index 7a5581b5..4d78fed8 100644 --- a/engine/core/math/aabb.h +++ b/engine/core/math/aabb.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef AABB_H -#define AABB_H +#pragma once #include "core/math/plane.h" #include "core/math/vector3.h" @@ -59,10 +58,15 @@ struct [[nodiscard]] AABB { const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } - bool operator==(const AABB &p_rval) const; - bool operator!=(const AABB &p_rval) const; + constexpr bool operator==(const AABB &p_rval) const { + return position == p_rval.position && size == p_rval.size; + } + constexpr bool operator!=(const AABB &p_rval) const { + return position != p_rval.position || size != p_rval.size; + } bool is_equal_approx(const AABB &p_aabb) const; + bool is_same(const AABB &p_aabb) const; bool is_finite() const; _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap @@ -129,8 +133,8 @@ struct [[nodiscard]] AABB { operator String() const; - _FORCE_INLINE_ AABB() {} - inline AABB(const Vector3 &p_pos, const Vector3 &p_size) : + AABB() = default; + constexpr AABB(const Vector3 &p_pos, const Vector3 &p_size) : position(p_pos), size(p_size) { } @@ -496,4 +500,5 @@ AABB AABB::quantized(real_t p_unit) const { return ret; } -#endif // AABB_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/audio_frame.h b/engine/core/math/audio_frame.h index e205126c..ff0f9a5b 100644 --- a/engine/core/math/audio_frame.h +++ b/engine/core/math/audio_frame.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef AUDIO_FRAME_H -#define AUDIO_FRAME_H +#pragma once #include "core/math/vector2.h" #include "core/typedefs.h" @@ -53,6 +52,7 @@ static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear_to_db(AUDIO_PEAK_OFFSE struct AudioFrame { // Left and right samples. union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { float left; float right; @@ -64,6 +64,7 @@ struct AudioFrame { }; #endif float levels[2] = { 0.0 }; + // NOLINTEND(modernize-use-default-member-init) }; _ALWAYS_INLINE_ const float &operator[](int p_idx) const { @@ -75,46 +76,46 @@ struct AudioFrame { return levels[p_idx]; } - _ALWAYS_INLINE_ AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); } - _ALWAYS_INLINE_ AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); } - _ALWAYS_INLINE_ AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); } - _ALWAYS_INLINE_ AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); } + constexpr AudioFrame operator+(const AudioFrame &p_frame) const { return AudioFrame(left + p_frame.left, right + p_frame.right); } + constexpr AudioFrame operator-(const AudioFrame &p_frame) const { return AudioFrame(left - p_frame.left, right - p_frame.right); } + constexpr AudioFrame operator*(const AudioFrame &p_frame) const { return AudioFrame(left * p_frame.left, right * p_frame.right); } + constexpr AudioFrame operator/(const AudioFrame &p_frame) const { return AudioFrame(left / p_frame.left, right / p_frame.right); } - _ALWAYS_INLINE_ AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); } - _ALWAYS_INLINE_ AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); } - _ALWAYS_INLINE_ AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); } - _ALWAYS_INLINE_ AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); } + constexpr AudioFrame operator+(float p_sample) const { return AudioFrame(left + p_sample, right + p_sample); } + constexpr AudioFrame operator-(float p_sample) const { return AudioFrame(left - p_sample, right - p_sample); } + constexpr AudioFrame operator*(float p_sample) const { return AudioFrame(left * p_sample, right * p_sample); } + constexpr AudioFrame operator/(float p_sample) const { return AudioFrame(left / p_sample, right / p_sample); } - _ALWAYS_INLINE_ void operator+=(const AudioFrame &p_frame) { + constexpr void operator+=(const AudioFrame &p_frame) { left += p_frame.left; right += p_frame.right; } - _ALWAYS_INLINE_ void operator-=(const AudioFrame &p_frame) { + constexpr void operator-=(const AudioFrame &p_frame) { left -= p_frame.left; right -= p_frame.right; } - _ALWAYS_INLINE_ void operator*=(const AudioFrame &p_frame) { + constexpr void operator*=(const AudioFrame &p_frame) { left *= p_frame.left; right *= p_frame.right; } - _ALWAYS_INLINE_ void operator/=(const AudioFrame &p_frame) { + constexpr void operator/=(const AudioFrame &p_frame) { left /= p_frame.left; right /= p_frame.right; } - _ALWAYS_INLINE_ void operator+=(float p_sample) { + constexpr void operator+=(float p_sample) { left += p_sample; right += p_sample; } - _ALWAYS_INLINE_ void operator-=(float p_sample) { + constexpr void operator-=(float p_sample) { left -= p_sample; right -= p_sample; } - _ALWAYS_INLINE_ void operator*=(float p_sample) { + constexpr void operator*=(float p_sample) { left *= p_sample; right *= p_sample; } - _ALWAYS_INLINE_ void operator/=(float p_sample) { + constexpr void operator/=(float p_sample) { left /= p_sample; right /= p_sample; } @@ -133,41 +134,41 @@ struct AudioFrame { return res; } - _ALWAYS_INLINE_ AudioFrame(float p_left, float p_right) { - left = p_left; - right = p_right; - } - _ALWAYS_INLINE_ AudioFrame(const AudioFrame &p_frame) { + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) + constexpr AudioFrame(float p_left, float p_right) : + left(p_left), right(p_right) {} + constexpr AudioFrame(const AudioFrame &p_frame) : + left(p_frame.left), right(p_frame.right) {} + // NOLINTEND(cppcoreguidelines-pro-type-member-init) + + constexpr void operator=(const AudioFrame &p_frame) { left = p_frame.left; right = p_frame.right; } - _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) { - left = p_frame.left; - right = p_frame.right; - } - - _ALWAYS_INLINE_ operator Vector2() const { + constexpr operator Vector2() const { return Vector2(left, right); } - _ALWAYS_INLINE_ AudioFrame(const Vector2 &p_v2) { - left = p_v2.x; - right = p_v2.y; - } - _ALWAYS_INLINE_ AudioFrame() {} + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) + constexpr AudioFrame(const Vector2 &p_v2) : + left(p_v2.x), right(p_v2.y) {} + constexpr AudioFrame() : + left(0), right(0) {} + // NOLINTEND(cppcoreguidelines-pro-type-member-init) }; -_ALWAYS_INLINE_ AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) { +constexpr AudioFrame operator*(float p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -_ALWAYS_INLINE_ AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) { +constexpr AudioFrame operator*(int32_t p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -_ALWAYS_INLINE_ AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) { +constexpr AudioFrame operator*(int64_t p_scalar, const AudioFrame &p_frame) { return AudioFrame(p_frame.left * p_scalar, p_frame.right * p_scalar); } -#endif // AUDIO_FRAME_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/basis.cpp b/engine/core/math/basis.cpp index 18959f3c..191f8a6a 100644 --- a/engine/core/math/basis.cpp +++ b/engine/core/math/basis.cpp @@ -186,7 +186,7 @@ Basis Basis::diagonalize() { // Compute the rotation angle real_t angle; if (Math::is_equal_approx(rows[j][j], rows[i][i])) { - angle = Math_PI / 4; + angle = Math::PI / 4; } else { angle = 0.5f * Math::atan(2 * rows[i][j] / (rows[j][j] - rows[i][i])); } @@ -486,12 +486,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } } else { euler.x = Math::atan2(rows[2][1], rows[1][1]); - euler.y = -Math_PI / 2.0f; + euler.y = -Math::PI / 2.0f; euler.z = 0.0f; } } else { euler.x = Math::atan2(rows[2][1], rows[1][1]); - euler.y = Math_PI / 2.0f; + euler.y = Math::PI / 2.0f; euler.z = 0.0f; } return euler; @@ -515,13 +515,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // It's -1 euler.x = -Math::atan2(rows[1][2], rows[2][2]); euler.y = 0.0f; - euler.z = Math_PI / 2.0f; + euler.z = Math::PI / 2.0f; } } else { // It's 1 euler.x = -Math::atan2(rows[1][2], rows[2][2]); euler.y = 0.0f; - euler.z = -Math_PI / 2.0f; + euler.z = -Math::PI / 2.0f; } return euler; } @@ -551,12 +551,12 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = atan2(rows[1][0], rows[1][1]); } } else { // m12 == -1 - euler.x = Math_PI * 0.5f; + euler.x = Math::PI * 0.5f; euler.y = atan2(rows[0][1], rows[0][0]); euler.z = 0; } } else { // m12 == 1 - euler.x = -Math_PI * 0.5f; + euler.x = -Math::PI * 0.5f; euler.y = -atan2(rows[0][1], rows[0][0]); euler.z = 0; } @@ -582,13 +582,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { // It's -1 euler.x = Math::atan2(rows[2][1], rows[2][2]); euler.y = 0.0f; - euler.z = -Math_PI / 2.0f; + euler.z = -Math::PI / 2.0f; } } else { // It's 1 euler.x = Math::atan2(rows[2][1], rows[2][2]); euler.y = 0.0f; - euler.z = Math_PI / 2.0f; + euler.z = Math::PI / 2.0f; } return euler; } break; @@ -608,13 +608,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { euler.z = Math::atan2(-rows[0][1], rows[1][1]); } else { // It's -1 - euler.x = -Math_PI / 2.0f; + euler.x = -Math::PI / 2.0f; euler.y = Math::atan2(rows[0][2], rows[0][0]); euler.z = 0; } } else { // It's 1 - euler.x = Math_PI / 2.0f; + euler.x = Math::PI / 2.0f; euler.y = Math::atan2(rows[0][2], rows[0][0]); euler.z = 0; } @@ -637,13 +637,13 @@ Vector3 Basis::get_euler(EulerOrder p_order) const { } else { // It's -1 euler.x = 0; - euler.y = Math_PI / 2.0f; + euler.y = Math::PI / 2.0f; euler.z = -Math::atan2(rows[0][1], rows[1][1]); } } else { // It's 1 euler.x = 0; - euler.y = -Math_PI / 2.0f; + euler.y = -Math::PI / 2.0f; euler.z = -Math::atan2(rows[0][1], rows[1][1]); } return euler; @@ -699,26 +699,14 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return rows[0].is_equal_approx(p_basis.rows[0]) && rows[1].is_equal_approx(p_basis.rows[1]) && rows[2].is_equal_approx(p_basis.rows[2]); } +bool Basis::is_same(const Basis &p_basis) const { + return rows[0].is_same(p_basis.rows[0]) && rows[1].is_same(p_basis.rows[1]) && rows[2].is_same(p_basis.rows[2]); +} + bool Basis::is_finite() const { return rows[0].is_finite() && rows[1].is_finite() && rows[2].is_finite(); } -bool Basis::operator==(const Basis &p_matrix) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (rows[i][j] != p_matrix.rows[i][j]) { - return false; - } - } - } - - return true; -} - -bool Basis::operator!=(const Basis &p_matrix) const { - return (!(*this == p_matrix)); -} - Basis::operator String() const { return "[X: " + get_column(0).operator String() + ", Y: " + get_column(1).operator String() + @@ -790,8 +778,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { if ((xx > yy) && (xx > zz)) { // rows[0][0] is the largest diagonal term. if (xx < CMP_EPSILON) { x = 0; - y = Math_SQRT12; - z = Math_SQRT12; + y = Math::SQRT12; + z = Math::SQRT12; } else { x = Math::sqrt(xx); y = xy / x; @@ -799,9 +787,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } else if (yy > zz) { // rows[1][1] is the largest diagonal term. if (yy < CMP_EPSILON) { - x = Math_SQRT12; + x = Math::SQRT12; y = 0; - z = Math_SQRT12; + z = Math::SQRT12; } else { y = Math::sqrt(yy); x = xy / y; @@ -809,8 +797,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } else { // rows[2][2] is the largest diagonal term so base result on this. if (zz < CMP_EPSILON) { - x = Math_SQRT12; - y = Math_SQRT12; + x = Math::SQRT12; + y = Math::SQRT12; z = 0; } else { z = Math::sqrt(zz); @@ -819,7 +807,7 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { } } r_axis = Vector3(x, y, z); - r_angle = Math_PI; + r_angle = Math::PI; return; } // As we have reached here there are no singularities so we can handle normally. diff --git a/engine/core/math/basis.h b/engine/core/math/basis.h index 2d4994de..e85437e7 100644 --- a/engine/core/math/basis.h +++ b/engine/core/math/basis.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef BASIS_H -#define BASIS_H +#pragma once #include "core/math/quaternion.h" #include "core/math/vector3.h" @@ -41,10 +40,10 @@ struct [[nodiscard]] Basis { Vector3(0, 0, 1) }; - _FORCE_INLINE_ const Vector3 &operator[](int p_row) const { + constexpr const Vector3 &operator[](int p_row) const { return rows[p_row]; } - _FORCE_INLINE_ Vector3 &operator[](int p_row) { + constexpr Vector3 &operator[](int p_row) { return rows[p_row]; } @@ -121,23 +120,24 @@ struct [[nodiscard]] Basis { } bool is_equal_approx(const Basis &p_basis) const; + bool is_same(const Basis &p_basis) const; bool is_finite() const; - bool operator==(const Basis &p_matrix) const; - bool operator!=(const Basis &p_matrix) const; + constexpr bool operator==(const Basis &p_matrix) const; + constexpr bool operator!=(const Basis &p_matrix) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const; _FORCE_INLINE_ void operator*=(const Basis &p_matrix); _FORCE_INLINE_ Basis operator*(const Basis &p_matrix) const; - _FORCE_INLINE_ void operator+=(const Basis &p_matrix); - _FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const; - _FORCE_INLINE_ void operator-=(const Basis &p_matrix); - _FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const; - _FORCE_INLINE_ void operator*=(real_t p_val); - _FORCE_INLINE_ Basis operator*(real_t p_val) const; - _FORCE_INLINE_ void operator/=(real_t p_val); - _FORCE_INLINE_ Basis operator/(real_t p_val) const; + constexpr void operator+=(const Basis &p_matrix); + constexpr Basis operator+(const Basis &p_matrix) const; + constexpr void operator-=(const Basis &p_matrix); + constexpr Basis operator-(const Basis &p_matrix) const; + constexpr void operator*=(real_t p_val); + constexpr Basis operator*(real_t p_val) const; + constexpr void operator/=(real_t p_val); + constexpr Basis operator/(real_t p_val) const; bool is_orthogonal() const; bool is_orthonormal() const; @@ -204,9 +204,12 @@ struct [[nodiscard]] Basis { rows[0].z * p_m[0].y + rows[1].z * p_m[1].y + rows[2].z * p_m[2].y, rows[0].z * p_m[0].z + rows[1].z * p_m[1].z + rows[2].z * p_m[2].z); } - Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) { - set(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz); - } + constexpr Basis(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz) : + rows{ + { p_xx, p_xy, p_xz }, + { p_yx, p_yy, p_yz }, + { p_zx, p_zy, p_zz }, + } {} void orthonormalize(); Basis orthonormalized() const; @@ -230,17 +233,36 @@ struct [[nodiscard]] Basis { Basis(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_angle, p_scale); } static Basis from_scale(const Vector3 &p_scale); - _FORCE_INLINE_ Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) { - set_columns(p_x_axis, p_y_axis, p_z_axis); - } + constexpr Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) : + rows{ + { p_x_axis.x, p_y_axis.x, p_z_axis.x }, + { p_x_axis.y, p_y_axis.y, p_z_axis.y }, + { p_x_axis.z, p_y_axis.z, p_z_axis.z }, + } {} - _FORCE_INLINE_ Basis() {} + Basis() = default; private: // Helper method. void _set_diagonal(const Vector3 &p_diag); }; +constexpr bool Basis::operator==(const Basis &p_matrix) const { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (rows[i][j] != p_matrix.rows[i][j]) { + return false; + } + } + } + + return true; +} + +constexpr bool Basis::operator!=(const Basis &p_matrix) const { + return (!(*this == p_matrix)); +} + _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) { set( p_matrix.tdotx(rows[0]), p_matrix.tdoty(rows[0]), p_matrix.tdotz(rows[0]), @@ -255,49 +277,49 @@ _FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const { p_matrix.tdotx(rows[2]), p_matrix.tdoty(rows[2]), p_matrix.tdotz(rows[2])); } -_FORCE_INLINE_ void Basis::operator+=(const Basis &p_matrix) { +constexpr void Basis::operator+=(const Basis &p_matrix) { rows[0] += p_matrix.rows[0]; rows[1] += p_matrix.rows[1]; rows[2] += p_matrix.rows[2]; } -_FORCE_INLINE_ Basis Basis::operator+(const Basis &p_matrix) const { +constexpr Basis Basis::operator+(const Basis &p_matrix) const { Basis ret(*this); ret += p_matrix; return ret; } -_FORCE_INLINE_ void Basis::operator-=(const Basis &p_matrix) { +constexpr void Basis::operator-=(const Basis &p_matrix) { rows[0] -= p_matrix.rows[0]; rows[1] -= p_matrix.rows[1]; rows[2] -= p_matrix.rows[2]; } -_FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const { +constexpr Basis Basis::operator-(const Basis &p_matrix) const { Basis ret(*this); ret -= p_matrix; return ret; } -_FORCE_INLINE_ void Basis::operator*=(real_t p_val) { +constexpr void Basis::operator*=(real_t p_val) { rows[0] *= p_val; rows[1] *= p_val; rows[2] *= p_val; } -_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const { +constexpr Basis Basis::operator*(real_t p_val) const { Basis ret(*this); ret *= p_val; return ret; } -_FORCE_INLINE_ void Basis::operator/=(real_t p_val) { +constexpr void Basis::operator/=(real_t p_val) { rows[0] /= p_val; rows[1] /= p_val; rows[2] /= p_val; } -_FORCE_INLINE_ Basis Basis::operator/(real_t p_val) const { +constexpr Basis Basis::operator/(real_t p_val) const { Basis ret(*this); ret /= p_val; return ret; @@ -322,5 +344,3 @@ real_t Basis::determinant() const { rows[1][0] * (rows[0][1] * rows[2][2] - rows[2][1] * rows[0][2]) + rows[2][0] * (rows[0][1] * rows[1][2] - rows[1][1] * rows[0][2]); } - -#endif // BASIS_H diff --git a/engine/core/math/bvh.h b/engine/core/math/bvh.h index 4815466e..9a9dde17 100644 --- a/engine/core/math/bvh.h +++ b/engine/core/math/bvh.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef BVH_H -#define BVH_H +#pragma once // BVH // This class provides a wrapper around BVH tree, which contains most of the functionality @@ -52,6 +51,8 @@ // and pairable_mask is either 0 if static, or set to all if non static #include "bvh_tree.h" + +#include "core/math/geometry_3d.h" #include "core/os/mutex.h" #define BVHTREE_CLASS BVH_Tree @@ -405,7 +406,7 @@ public: } Vector convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size()); - if (convex_points.size() == 0) { + if (convex_points.is_empty()) { return 0; } @@ -435,8 +436,6 @@ private: return; } - BOUNDS bb; - typename BVHTREE_CLASS::CullParams params; params.result_count_overall = 0; @@ -806,5 +805,3 @@ public: }; #undef BVHTREE_CLASS - -#endif // BVH_H diff --git a/engine/core/math/bvh_abb.h b/engine/core/math/bvh_abb.h index 3d32c250..b96ea085 100644 --- a/engine/core/math/bvh_abb.h +++ b/engine/core/math/bvh_abb.h @@ -28,8 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef BVH_ABB_H -#define BVH_ABB_H +#pragma once + +#include "core/math/aabb.h" // special optimized version of axis aligned bounding box template @@ -288,5 +289,3 @@ struct BVH_ABB { return false; } }; - -#endif // BVH_ABB_H diff --git a/engine/core/math/bvh_tree.h b/engine/core/math/bvh_tree.h index 2a2a6d67..76e5c999 100644 --- a/engine/core/math/bvh_tree.h +++ b/engine/core/math/bvh_tree.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef BVH_TREE_H -#define BVH_TREE_H +#pragma once // BVH Tree // This is an implementation of a dynamic BVH with templated leaf size. @@ -41,7 +40,6 @@ #include "core/math/aabb.h" #include "core/math/bvh_abb.h" -#include "core/math/geometry_3d.h" #include "core/math/vector3.h" #include "core/templates/local_vector.h" #include "core/templates/pooled_list.h" @@ -454,5 +452,3 @@ private: }; #undef VERBOSE_PRINT - -#endif // BVH_TREE_H diff --git a/engine/core/math/color.cpp b/engine/core/math/color.cpp index 4c31d814..d032a3fe 100644 --- a/engine/core/math/color.cpp +++ b/engine/core/math/color.cpp @@ -109,36 +109,27 @@ uint64_t Color::to_rgba64() const { return c; } -String _to_hex(float p_val) { +void _append_hex(float p_val, char32_t *string) { int v = Math::round(p_val * 255.0f); v = CLAMP(v, 0, 255); - String ret; - for (int i = 0; i < 2; i++) { - char32_t c[2] = { 0, 0 }; - int lv = v & 0xF; - if (lv < 10) { - c[0] = '0' + lv; - } else { - c[0] = 'a' + lv - 10; - } - - v >>= 4; - String cs = (const char32_t *)c; - ret = cs + ret; - } - - return ret; + string[0] = hex_char_table_lower[(v >> 4) & 0xF]; + string[1] = hex_char_table_lower[v & 0xF]; } String Color::to_html(bool p_alpha) const { String txt; - txt += _to_hex(r); - txt += _to_hex(g); - txt += _to_hex(b); + txt.resize(p_alpha ? 9 : 7); + char32_t *ptr = txt.ptrw(); + + _append_hex(r, ptr + 0); + _append_hex(g, ptr + 2); + _append_hex(b, ptr + 4); if (p_alpha) { - txt += _to_hex(a); + _append_hex(a, ptr + 6); } + ptr[txt.size() - 1] = '\0'; + return txt; } @@ -259,6 +250,10 @@ 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); } +bool Color::is_same(const Color &p_color) const { + return Math::is_same(r, p_color.r) && Math::is_same(g, p_color.g) && Math::is_same(b, p_color.b) && Math::is_same(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), @@ -321,47 +316,38 @@ Color Color::inverted() const { } Color Color::html(const String &p_rgba) { - String color = p_rgba; - if (color.length() == 0) { + if (p_rgba.is_empty()) { return Color(); } - if (color[0] == '#') { - color = color.substr(1); - } - // If enabled, use 1 hex digit per channel instead of 2. - // Other sizes aren't in the HTML/CSS spec but we could add them if desired. - bool is_shorthand = color.length() < 5; - bool alpha = false; + const int current_pos = (p_rgba[0] == '#') ? 1 : 0; + const int num_of_digits = p_rgba.length() - current_pos; - if (color.length() == 8) { - alpha = true; - } else if (color.length() == 6) { - alpha = false; - } else if (color.length() == 4) { - alpha = true; - } else if (color.length() == 3) { - alpha = false; + float r, g, b, a = 1.0f; + + if (num_of_digits == 3) { + // #rgb + r = _parse_col4(p_rgba, current_pos) / 15.0f; + g = _parse_col4(p_rgba, current_pos + 1) / 15.0f; + b = _parse_col4(p_rgba, current_pos + 2) / 15.0f; + } else if (num_of_digits == 4) { + r = _parse_col4(p_rgba, current_pos) / 15.0f; + g = _parse_col4(p_rgba, current_pos + 1) / 15.0f; + b = _parse_col4(p_rgba, current_pos + 2) / 15.0f; + a = _parse_col4(p_rgba, current_pos + 3) / 15.0f; + } else if (num_of_digits == 6) { + r = _parse_col8(p_rgba, current_pos) / 255.0f; + g = _parse_col8(p_rgba, current_pos + 2) / 255.0f; + b = _parse_col8(p_rgba, current_pos + 4) / 255.0f; + } else if (num_of_digits == 8) { + r = _parse_col8(p_rgba, current_pos) / 255.0f; + g = _parse_col8(p_rgba, current_pos + 2) / 255.0f; + b = _parse_col8(p_rgba, current_pos + 4) / 255.0f; + a = _parse_col8(p_rgba, current_pos + 6) / 255.0f; } else { ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + "."); } - float r, g, b, a = 1.0f; - if (is_shorthand) { - r = _parse_col4(color, 0) / 15.0f; - g = _parse_col4(color, 1) / 15.0f; - b = _parse_col4(color, 2) / 15.0f; - if (alpha) { - a = _parse_col4(color, 3) / 15.0f; - } - } else { - r = _parse_col8(color, 0) / 255.0f; - g = _parse_col8(color, 2) / 255.0f; - b = _parse_col8(color, 4) / 255.0f; - if (alpha) { - a = _parse_col8(color, 6) / 255.0f; - } - } ERR_FAIL_COND_V_MSG(r < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); ERR_FAIL_COND_V_MSG(g < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); ERR_FAIL_COND_V_MSG(b < 0.0f, Color(), "Invalid color code: " + p_rgba + "."); @@ -373,22 +359,20 @@ Color Color::html(const String &p_rgba) { bool Color::html_is_valid(const String &p_color) { String color = p_color; - if (color.length() == 0) { + if (color.is_empty()) { return false; } - if (color[0] == '#') { - color = color.substr(1); - } - // Check if the amount of hex digits is valid. - int len = color.length(); - if (!(len == 3 || len == 4 || len == 6 || len == 8)) { + const int current_pos = (color[0] == '#') ? 1 : 0; + const int len = color.length(); + const int num_of_digits = len - current_pos; + if (!(num_of_digits == 3 || num_of_digits == 4 || num_of_digits == 6 || num_of_digits == 8)) { return false; } // Check if each hex digit is valid. - for (int i = 0; i < len; i++) { - if (_parse_col4(color, i) == -1) { + for (int i = current_pos; i < len; i++) { + if (!is_hex_digit(p_color[i])) { return false; } } @@ -415,18 +399,14 @@ Color Color::named(const String &p_name, const Color &p_default) { int Color::find_named_color(const String &p_name) { String name = p_name; // Normalize name. - name = name.replace(" ", ""); - name = name.replace("-", ""); - name = name.replace("_", ""); - name = name.replace("'", ""); - name = name.replace(".", ""); + name = name.remove_chars(" -_'."); name = name.to_upper(); static HashMap named_colors_hashmap; if (unlikely(named_colors_hashmap.is_empty())) { const int named_color_count = get_named_color_count(); for (int i = 0; i < named_color_count; i++) { - named_colors_hashmap[String(named_colors[i].name).replace("_", "")] = i; + named_colors_hashmap[String(named_colors[i].name).remove_char('_')] = i; } } @@ -439,7 +419,7 @@ int Color::find_named_color(const String &p_name) { } int Color::get_named_color_count() { - return sizeof(named_colors) / sizeof(NamedColor); + return std::size(named_colors); } String Color::get_named_color_name(int p_idx) { @@ -490,104 +470,6 @@ Color::operator String() const { return "(" + String::num(r, 4) + ", " + String::num(g, 4) + ", " + String::num(b, 4) + ", " + String::num(a, 4) + ")"; } -Color Color::operator+(const Color &p_color) const { - return Color( - r + p_color.r, - g + p_color.g, - b + p_color.b, - a + p_color.a); -} - -void Color::operator+=(const Color &p_color) { - r = r + p_color.r; - g = g + p_color.g; - b = b + p_color.b; - a = a + p_color.a; -} - -Color Color::operator-(const Color &p_color) const { - return Color( - r - p_color.r, - g - p_color.g, - b - p_color.b, - a - p_color.a); -} - -void Color::operator-=(const Color &p_color) { - r = r - p_color.r; - g = g - p_color.g; - b = b - p_color.b; - a = a - p_color.a; -} - -Color Color::operator*(const Color &p_color) const { - return Color( - r * p_color.r, - g * p_color.g, - b * p_color.b, - a * p_color.a); -} - -Color Color::operator*(float p_scalar) const { - return Color( - r * p_scalar, - g * p_scalar, - b * p_scalar, - a * p_scalar); -} - -void Color::operator*=(const Color &p_color) { - r = r * p_color.r; - g = g * p_color.g; - b = b * p_color.b; - a = a * p_color.a; -} - -void Color::operator*=(float p_scalar) { - r = r * p_scalar; - g = g * p_scalar; - b = b * p_scalar; - a = a * p_scalar; -} - -Color Color::operator/(const Color &p_color) const { - return Color( - r / p_color.r, - g / p_color.g, - b / p_color.b, - a / p_color.a); -} - -Color Color::operator/(float p_scalar) const { - return Color( - r / p_scalar, - g / p_scalar, - b / p_scalar, - a / p_scalar); -} - -void Color::operator/=(const Color &p_color) { - r = r / p_color.r; - g = g / p_color.g; - b = b / p_color.b; - a = a / p_color.a; -} - -void Color::operator/=(float p_scalar) { - r = r / p_scalar; - g = g / p_scalar; - b = b / p_scalar; - a = a / p_scalar; -} - -Color Color::operator-() const { - return Color( - 1.0f - r, - 1.0f - g, - 1.0f - b, - 1.0f - a); -} - Color Color::from_ok_hsl(float p_h, float p_s, float p_l, float p_alpha) { Color c; c.set_ok_hsl(p_h, p_s, p_l, p_alpha); diff --git a/engine/core/math/color.h b/engine/core/math/color.h index c2ffde18..ae91677d 100644 --- a/engine/core/math/color.h +++ b/engine/core/math/color.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef COLOR_H -#define COLOR_H +#pragma once #include "core/math/math_funcs.h" @@ -37,6 +36,7 @@ class String; struct [[nodiscard]] Color { union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { float r; float g; @@ -44,6 +44,7 @@ struct [[nodiscard]] Color { float a; }; float components[4] = { 0, 0, 0, 1.0 }; + // NOLINTEND(modernize-use-default-member-init) }; uint32_t to_rgba32() const; @@ -69,31 +70,32 @@ struct [[nodiscard]] Color { return components[p_idx]; } - bool operator==(const Color &p_color) const { + constexpr bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } - bool operator!=(const Color &p_color) const { + constexpr bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); } - Color operator+(const Color &p_color) const; - void operator+=(const Color &p_color); + constexpr Color operator+(const Color &p_color) const; + constexpr void operator+=(const Color &p_color); - Color operator-() const; - Color operator-(const Color &p_color) const; - void operator-=(const Color &p_color); + constexpr Color operator-() const; + constexpr Color operator-(const Color &p_color) const; + constexpr void operator-=(const Color &p_color); - Color operator*(const Color &p_color) const; - Color operator*(float p_scalar) const; - void operator*=(const Color &p_color); - void operator*=(float p_scalar); + constexpr Color operator*(const Color &p_color) const; + constexpr Color operator*(float p_scalar) const; + constexpr void operator*=(const Color &p_color); + constexpr void operator*=(float p_scalar); - Color operator/(const Color &p_color) const; - Color operator/(float p_scalar) const; - void operator/=(const Color &p_color); - void operator/=(float p_scalar); + constexpr Color operator/(const Color &p_color) const; + constexpr Color operator/(float p_scalar) const; + constexpr void operator/=(const Color &p_color); + constexpr void operator/=(float p_scalar); bool is_equal_approx(const Color &p_color) const; + bool is_same(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(); @@ -215,7 +217,7 @@ struct [[nodiscard]] Color { static Color from_rgbe9995(uint32_t p_rgbe); static Color from_rgba8(int64_t p_r8, int64_t p_g8, int64_t p_b8, int64_t p_a8 = 255); - _FORCE_INLINE_ bool operator<(const Color &p_color) const; // Used in set keys. + constexpr bool operator<(const Color &p_color) const; // Used in set keys. operator String() const; // For the binder. @@ -235,39 +237,29 @@ struct [[nodiscard]] Color { _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l(), a); } _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l, a); } - _FORCE_INLINE_ Color() {} + constexpr Color() : + r(0), g(0), b(0), a(1) {} /** * RGBA construct parameters. * Alpha is not optional as otherwise we can't bind the RGB version for scripting. */ - _FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a) { - r = p_r; - g = p_g; - b = p_b; - a = p_a; - } + constexpr Color(float p_r, float p_g, float p_b, float p_a) : + r(p_r), g(p_g), b(p_b), a(p_a) {} /** * RGB construct parameters. */ - _FORCE_INLINE_ Color(float p_r, float p_g, float p_b) { - r = p_r; - g = p_g; - b = p_b; - a = 1.0f; - } + constexpr Color(float p_r, float p_g, float p_b) : + r(p_r), g(p_g), b(p_b), a(1) {} /** * Construct a Color from another Color, but with the specified alpha value. */ - _FORCE_INLINE_ Color(const Color &p_c, float p_a) { - r = p_c.r; - g = p_c.g; - b = p_c.b; - a = p_a; - } + constexpr Color(const Color &p_c, float p_a) : + r(p_c.r), g(p_c.g), b(p_c.b), a(p_a) {} + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) Color(const String &p_code) { if (html_is_valid(p_code)) { *this = html(p_code); @@ -280,9 +272,108 @@ struct [[nodiscard]] Color { *this = Color(p_code); a = p_a; } + // NOLINTEND(cppcoreguidelines-pro-type-member-init) }; -bool Color::operator<(const Color &p_color) const { +constexpr Color Color::operator+(const Color &p_color) const { + return Color( + r + p_color.r, + g + p_color.g, + b + p_color.b, + a + p_color.a); +} + +constexpr void Color::operator+=(const Color &p_color) { + r = r + p_color.r; + g = g + p_color.g; + b = b + p_color.b; + a = a + p_color.a; +} + +constexpr Color Color::operator-(const Color &p_color) const { + return Color( + r - p_color.r, + g - p_color.g, + b - p_color.b, + a - p_color.a); +} + +constexpr void Color::operator-=(const Color &p_color) { + r = r - p_color.r; + g = g - p_color.g; + b = b - p_color.b; + a = a - p_color.a; +} + +constexpr Color Color::operator*(const Color &p_color) const { + return Color( + r * p_color.r, + g * p_color.g, + b * p_color.b, + a * p_color.a); +} + +constexpr Color Color::operator*(float p_scalar) const { + return Color( + r * p_scalar, + g * p_scalar, + b * p_scalar, + a * p_scalar); +} + +constexpr void Color::operator*=(const Color &p_color) { + r = r * p_color.r; + g = g * p_color.g; + b = b * p_color.b; + a = a * p_color.a; +} + +constexpr void Color::operator*=(float p_scalar) { + r = r * p_scalar; + g = g * p_scalar; + b = b * p_scalar; + a = a * p_scalar; +} + +constexpr Color Color::operator/(const Color &p_color) const { + return Color( + r / p_color.r, + g / p_color.g, + b / p_color.b, + a / p_color.a); +} + +constexpr Color Color::operator/(float p_scalar) const { + return Color( + r / p_scalar, + g / p_scalar, + b / p_scalar, + a / p_scalar); +} + +constexpr void Color::operator/=(const Color &p_color) { + r = r / p_color.r; + g = g / p_color.g; + b = b / p_color.b; + a = a / p_color.a; +} + +constexpr void Color::operator/=(float p_scalar) { + r = r / p_scalar; + g = g / p_scalar; + b = b / p_scalar; + a = a / p_scalar; +} + +constexpr Color Color::operator-() const { + return Color( + 1.0f - r, + 1.0f - g, + 1.0f - b, + 1.0f - a); +} + +constexpr bool Color::operator<(const Color &p_color) const { if (r == p_color.r) { if (g == p_color.g) { if (b == p_color.b) { @@ -298,8 +389,6 @@ bool Color::operator<(const Color &p_color) const { } } -_FORCE_INLINE_ Color operator*(float p_scalar, const Color &p_color) { +constexpr Color operator*(float p_scalar, const Color &p_color) { return p_color * p_scalar; } - -#endif // COLOR_H diff --git a/engine/core/math/color_names.inc b/engine/core/math/color_names.inc index 6c0d2a4b..969acc68 100644 --- a/engine/core/math/color_names.inc +++ b/engine/core/math/color_names.inc @@ -28,12 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ +#pragma once + // Names from https://en.wikipedia.org/wiki/X11_color_names // So this in a way that does not require memory allocation // the old way leaked memory // this is not used as often as for more performance to make sense +#include "core/math/color.h" + struct NamedColor { const char *name; Color color; diff --git a/engine/core/math/convex_hull.cpp b/engine/core/math/convex_hull.cpp index 4052234f..fbd367b9 100644 --- a/engine/core/math/convex_hull.cpp +++ b/engine/core/math/convex_hull.cpp @@ -2237,7 +2237,7 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea Error ConvexHullComputer::convex_hull(const Vector &p_points, Geometry3D::MeshData &r_mesh) { r_mesh = Geometry3D::MeshData(); // clear - if (p_points.size() == 0) { + if (p_points.is_empty()) { return FAILED; // matches QuickHull } diff --git a/engine/core/math/convex_hull.h b/engine/core/math/convex_hull.h index 75787f7b..9af39790 100644 --- a/engine/core/math/convex_hull.h +++ b/engine/core/math/convex_hull.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CONVEX_HULL_H -#define CONVEX_HULL_H +#pragma once /* Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net @@ -112,5 +111,3 @@ public: static Error convex_hull(const Vector &p_points, Geometry3D::MeshData &r_mesh); }; - -#endif // CONVEX_HULL_H diff --git a/engine/core/math/delaunay_2d.h b/engine/core/math/delaunay_2d.h index 0bc67a92..cb0eca2b 100644 --- a/engine/core/math/delaunay_2d.h +++ b/engine/core/math/delaunay_2d.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DELAUNAY_2D_H -#define DELAUNAY_2D_H +#pragma once #include "core/math/rect2.h" #include "core/templates/vector.h" @@ -156,5 +155,3 @@ public: return triangles; } }; - -#endif // DELAUNAY_2D_H diff --git a/engine/core/math/delaunay_3d.h b/engine/core/math/delaunay_3d.h index 5bbdcc09..122ff945 100644 --- a/engine/core/math/delaunay_3d.h +++ b/engine/core/math/delaunay_3d.h @@ -28,17 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DELAUNAY_3D_H -#define DELAUNAY_3D_H +#pragma once -#include "core/io/file_access.h" #include "core/math/aabb.h" #include "core/math/projection.h" #include "core/math/vector3.h" +#include "core/templates/list.h" #include "core/templates/local_vector.h" #include "core/templates/oa_hash_map.h" #include "core/templates/vector.h" -#include "core/variant/variant.h" #include "thirdparty/misc/r128.h" @@ -187,7 +185,7 @@ class Delaunay3D { Plane p(p_points[p_simplex.points[i]], p_points[p_simplex.points[(i + 1) % 4]], p_points[p_simplex.points[(i + 2) % 4]]); // This tolerance should not be smaller than the one used with // Plane::has_point() when creating the LightmapGI probe BSP tree. - if (ABS(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) { + if (Math::abs(p.distance_to(p_points[p_simplex.points[(i + 3) % 4]])) < 0.001) { return true; } } @@ -389,5 +387,3 @@ public: return ret_simplices; } }; - -#endif // DELAUNAY_3D_H diff --git a/engine/core/math/disjoint_set.h b/engine/core/math/disjoint_set.h index 4348da99..9345375f 100644 --- a/engine/core/math/disjoint_set.h +++ b/engine/core/math/disjoint_set.h @@ -28,10 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DISJOINT_SET_H -#define DISJOINT_SET_H +#pragma once -#include "core/templates/rb_map.h" +#include "core/templates/hash_map.h" #include "core/templates/vector.h" /* This DisjointSet class uses Find with path compression and Union by rank */ @@ -146,5 +145,3 @@ void DisjointSet::get_members(Vector &out_members, T representat } } } - -#endif // DISJOINT_SET_H diff --git a/engine/core/math/dynamic_bvh.cpp b/engine/core/math/dynamic_bvh.cpp index e1315d1c..1195072a 100644 --- a/engine/core/math/dynamic_bvh.cpp +++ b/engine/core/math/dynamic_bvh.cpp @@ -181,7 +181,7 @@ DynamicBVH::Volume DynamicBVH::_bounds(Node **leaves, int p_count) { void DynamicBVH::_bottom_up(Node **leaves, int p_count) { while (p_count > 1) { - real_t minsize = INFINITY; + real_t minsize = Math::INF; int minidx[2] = { -1, -1 }; for (int i = 0; i < p_count; ++i) { for (int j = i + 1; j < p_count; ++j) { diff --git a/engine/core/math/dynamic_bvh.h b/engine/core/math/dynamic_bvh.h index 26fc517f..10e4e063 100644 --- a/engine/core/math/dynamic_bvh.h +++ b/engine/core/math/dynamic_bvh.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef DYNAMIC_BVH_H -#define DYNAMIC_BVH_H +#pragma once #include "core/math/aabb.h" #include "core/templates/list.h" @@ -474,5 +473,3 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu } } while (depth > 0); } - -#endif // DYNAMIC_BVH_H diff --git a/engine/core/math/expression.cpp b/engine/core/math/expression.cpp index 26b773a2..0bfc8def 100644 --- a/engine/core/math/expression.cpp +++ b/engine/core/math/expression.cpp @@ -454,16 +454,16 @@ Error Expression::_get_token(Token &r_token) { r_token.value = false; } else if (id == "PI") { r_token.type = TK_CONSTANT; - r_token.value = Math_PI; + r_token.value = Math::PI; } else if (id == "TAU") { r_token.type = TK_CONSTANT; - r_token.value = Math_TAU; + r_token.value = Math::TAU; } else if (id == "INF") { r_token.type = TK_CONSTANT; - r_token.value = INFINITY; + r_token.value = Math::INF; } else if (id == "NAN") { r_token.type = TK_CONSTANT; - r_token.value = NAN; + r_token.value = Math::NaN; } else if (id == "not") { r_token.type = TK_OP_NOT; } else if (id == "or") { diff --git a/engine/core/math/expression.h b/engine/core/math/expression.h index 46bc3618..aea714cf 100644 --- a/engine/core/math/expression.h +++ b/engine/core/math/expression.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef EXPRESSION_H -#define EXPRESSION_H +#pragma once #include "core/object/ref_counted.h" @@ -271,5 +270,3 @@ public: Expression() {} ~Expression(); }; - -#endif // EXPRESSION_H diff --git a/engine/core/math/face3.cpp b/engine/core/math/face3.cpp index 1dff0ee4..b9ab85e4 100644 --- a/engine/core/math/face3.cpp +++ b/engine/core/math/face3.cpp @@ -263,7 +263,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform3D &p_transform, // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); - dot = ABS(dot); + dot = Math::abs(dot); if (dot < edge_support_threshold) { *p_count = MIN(2, p_max); diff --git a/engine/core/math/face3.h b/engine/core/math/face3.h index 519dcb64..b7472f9d 100644 --- a/engine/core/math/face3.h +++ b/engine/core/math/face3.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef FACE3_H -#define FACE3_H +#pragma once #include "core/math/aabb.h" #include "core/math/plane.h" @@ -79,12 +78,9 @@ struct [[nodiscard]] Face3 { _FORCE_INLINE_ bool intersects_aabb2(const AABB &p_aabb) const; operator String() const; - inline Face3() {} - inline Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) { - vertex[0] = p_v1; - vertex[1] = p_v2; - vertex[2] = p_v3; - } + Face3() = default; + constexpr Face3(const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) : + vertex{ p_v1, p_v2, p_v3 } {} }; bool Face3::intersects_aabb2(const AABB &p_aabb) const { @@ -238,4 +234,5 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const { return true; } -#endif // FACE3_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/geometry_2d.cpp b/engine/core/math/geometry_2d.cpp index 376d5d0b..30ea79a0 100644 --- a/engine/core/math/geometry_2d.cpp +++ b/engine/core/math/geometry_2d.cpp @@ -38,17 +38,63 @@ const int clipper_precision = 5; // Based on CMP_EPSILON. const double clipper_scale = Math::pow(10.0, clipper_precision); -Vector> Geometry2D::decompose_polygon_in_convex(const Vector &polygon) { +void Geometry2D::merge_many_polygons(const Vector> &p_polygons, Vector> &r_out_polygons, Vector> &r_out_holes) { + using namespace Clipper2Lib; + + PathsD subjects; + for (const Vector &polygon : p_polygons) { + PathD path(polygon.size()); + for (int i = 0; i < polygon.size(); i++) { + const Vector2 &point = polygon[i]; + path[i] = PointD(point.x, point.y); + } + subjects.push_back(path); + } + + PathsD solution = Union(subjects, FillRule::NonZero); + solution = SimplifyPaths(solution, 0.01); + + r_out_polygons.clear(); + r_out_holes.clear(); + for (PathsD::size_type i = 0; i < solution.size(); ++i) { + PathD &path = solution[i]; + + Vector output_polygon; + output_polygon.resize(path.size()); + for (PathsD::size_type j = 0; j < path.size(); ++j) { + output_polygon.set(j, Vector2(static_cast(path[j].x), static_cast(path[j].y))); + } + if (IsPositive(path)) { + r_out_polygons.push_back(output_polygon); + } else { + r_out_holes.push_back(output_polygon); + } + } +} + +Vector> Geometry2D::decompose_many_polygons_in_convex(const Vector> &p_polygons, const Vector> &p_holes) { Vector> decomp; List in_poly, out_poly; - TPPLPoly inp; - inp.Init(polygon.size()); - for (int i = 0; i < polygon.size(); i++) { - inp.GetPoint(i) = polygon[i]; + for (const Vector &polygon : p_polygons) { + TPPLPoly inp; + inp.Init(polygon.size()); + for (int i = 0; i < polygon.size(); i++) { + inp.GetPoint(i) = polygon[i]; + } + inp.SetOrientation(TPPL_ORIENTATION_CCW); + in_poly.push_back(inp); + } + for (const Vector &polygon : p_holes) { + TPPLPoly inp; + inp.Init(polygon.size()); + for (int i = 0; i < polygon.size(); i++) { + inp.GetPoint(i) = polygon[i]; + } + inp.SetOrientation(TPPL_ORIENTATION_CW); + inp.SetHole(true); + in_poly.push_back(inp); } - inp.SetOrientation(TPPL_ORIENTATION_CCW); - in_poly.push_back(inp); TPPLPartition tpart; if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed. ERR_PRINT("Convex decomposing failed!"); @@ -57,9 +103,7 @@ Vector> Geometry2D::decompose_polygon_in_convex(const Vector::Element *I = out_poly.front(); I; I = I->next()) { - TPPLPoly &tp = I->get(); - + for (TPPLPoly &tp : out_poly) { decomp.write[idx].resize(tp.GetNumPoints()); for (int64_t i = 0; i < tp.GetNumPoints(); i++) { @@ -72,6 +116,10 @@ Vector> Geometry2D::decompose_polygon_in_convex(const Vector> Geometry2D::decompose_polygon_in_convex(const Vector &p_polygon) { + return Geometry2D::decompose_many_polygons_in_convex({ p_polygon }, {}); +} + struct _AtlasWorkRect { Size2i s; Point2i p; diff --git a/engine/core/math/geometry_2d.h b/engine/core/math/geometry_2d.h index abd395d8..fa5b0f06 100644 --- a/engine/core/math/geometry_2d.h +++ b/engine/core/math/geometry_2d.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GEOMETRY_2D_H -#define GEOMETRY_2D_H +#pragma once #include "core/math/delaunay_2d.h" #include "core/math/math_funcs.h" @@ -100,27 +99,39 @@ public: return Math::sqrt((c1 - c2).dot(c1 - c2)); } +#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - Vector2 p = p_point - p_segment[0]; - Vector2 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + Vector2 p = p_point - p_segment_a; + Vector2 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment[0]; // Before first point. + return p_segment_a; // Before first point. } else if (d >= 1.0f) { - return p_segment[1]; // After first point. + return p_segment_b; // After first point. } else { - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } } +#ifndef DISABLE_DEPRECATED static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 *p_segment) { - return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment)); + return get_distance_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static real_t get_distance_to_segment(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + return p_point.distance_to(get_closest_point_to_segment(p_point, p_segment_a, p_segment_b)); } static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) { @@ -137,24 +148,26 @@ public: return (cn.cross(an) > 0) == orientation; } +#ifndef DISABLE_DEPRECATED static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 *p_segment) { - Vector2 p = p_point - p_segment[0]; - Vector2 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_segment_a, const Vector2 &p_segment_b) { + Vector2 p = p_point - p_segment_a; + Vector2 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } -// Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0. -// See: https://github.com/godotengine/godot/pull/44274 -#ifdef _MSC_VER -#pragma warning(disable : 4723) -#endif + GODOT_MSVC_WARNING_PUSH_AND_IGNORE(4723) // Potential divide by 0. False positive (see: GH-44274). static bool line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) { // See http://paulbourke.net/geometry/pointlineplane/ @@ -170,10 +183,7 @@ public: return true; } -// Re-enable division by 0 warning -#ifdef _MSC_VER -#pragma warning(default : 4723) -#endif + GODOT_MSVC_WARNING_POP static bool segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b, Vector2 *r_result) { Vector2 B = p_to_a - p_from_a; @@ -489,7 +499,10 @@ public: return points; } - static Vector> decompose_polygon_in_convex(const Vector &polygon); + static void merge_many_polygons(const Vector> &p_polygons, Vector> &r_out_polygons, Vector> &r_out_holes); + static Vector> decompose_many_polygons_in_convex(const Vector> &p_polygons, const Vector> &p_holes); + + static Vector> decompose_polygon_in_convex(const Vector &p_polygon); static void make_atlas(const Vector &p_rects, Vector &r_result, Size2i &r_size); static Vector partial_pack_rects(const Vector &p_sizes, const Size2i &p_atlas_size); @@ -498,5 +511,3 @@ private: static Vector> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector &p_polypath_a, const Vector &p_polypath_b, bool is_a_open = false); static Vector> _polypath_offset(const Vector &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type); }; - -#endif // GEOMETRY_2D_H diff --git a/engine/core/math/geometry_3d.cpp b/engine/core/math/geometry_3d.cpp index 361a0607..71559ead 100644 --- a/engine/core/math/geometry_3d.cpp +++ b/engine/core/math/geometry_3d.cpp @@ -30,6 +30,8 @@ #include "geometry_3d.h" +#include "core/templates/hash_map.h" + void Geometry3D::get_closest_points_between_segments(const Vector3 &p_p0, const Vector3 &p_p1, const Vector3 &p_q0, const Vector3 &p_q1, Vector3 &r_ps, Vector3 &r_qt) { // Based on David Eberly's Computation of Distance Between Line Segments algorithm. @@ -593,7 +595,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector &p_planes Vector3 ref = Vector3(0.0, 1.0, 0.0); - if (ABS(p.normal.dot(ref)) > 0.95f) { + if (Math::abs(p.normal.dot(ref)) > 0.95f) { ref = Vector3(0.0, 0.0, 1.0); // Change axis. } @@ -742,7 +744,7 @@ Vector Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height Vector planes; - const double sides_step = Math_TAU / p_sides; + const double sides_step = Math::TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); @@ -773,7 +775,7 @@ Vector Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; - const double lon_step = Math_TAU / p_lons; + const double lon_step = Math::TAU / p_lons; for (int i = 0; i < p_lons; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * lon_step); @@ -804,7 +806,7 @@ Vector Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; - const double sides_step = Math_TAU / p_sides; + const double sides_step = Math::TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); @@ -860,7 +862,6 @@ Vector Geometry3D::compute_convex_mesh_points(const Plane *p_planes, in } #define square(m_s) ((m_s) * (m_s)) -#define INF 1e20 /* dt of 1d function using squared distance */ static void edt(float *f, int stride, int n) { @@ -870,8 +871,8 @@ static void edt(float *f, int stride, int n) { int k = 0; v[0] = 0; - z[0] = -INF; - z[1] = +INF; + z[0] = -Math::INF; + z[1] = +Math::INF; for (int q = 1; q <= n - 1; q++) { float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]); while (s <= z[k]) { @@ -882,7 +883,7 @@ static void edt(float *f, int stride, int n) { v[k] = q; z[k] = s; - z[k + 1] = +INF; + z[k + 1] = +Math::INF; } k = 0; @@ -907,7 +908,7 @@ Vector Geometry3D::generate_edf(const Vector &p_voxels, const Ve float *work_memory = memnew_arr(float, float_count); for (uint32_t i = 0; i < float_count; i++) { - work_memory[i] = INF; + work_memory[i] = Math::INF; } uint32_t y_mult = p_size.x; diff --git a/engine/core/math/geometry_3d.h b/engine/core/math/geometry_3d.h index ff39d825..bd8dbe43 100644 --- a/engine/core/math/geometry_3d.h +++ b/engine/core/math/geometry_3d.h @@ -28,12 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef GEOMETRY_3D_H -#define GEOMETRY_3D_H +#pragma once #include "core/math/delaunay_3d.h" #include "core/math/face3.h" -#include "core/object/object.h" #include "core/templates/local_vector.h" #include "core/templates/vector.h" @@ -274,7 +272,7 @@ public: return true; } - static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *p_res, Vector3 *p_norm) { + static bool segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Plane *p_planes, int p_plane_count, Vector3 *r_res, Vector3 *r_norm) { real_t min = -1e20, max = 1e20; Vector3 rel = p_to - p_from; @@ -317,46 +315,58 @@ public: return false; // No intersection. } - if (p_res) { - *p_res = p_from + dir * min; + if (r_res) { + *r_res = p_from + dir * min; } - if (p_norm) { - *p_norm = p_planes[min_index].normal; + if (r_norm) { + *r_norm = p_planes[min_index].normal; } return true; } +#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 *p_segment) { - Vector3 p = p_point - p_segment[0]; - Vector3 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { + Vector3 p = p_point - p_segment_a; + Vector3 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; if (d <= 0.0f) { - return p_segment[0]; // Before first point. + return p_segment_a; // Before first point. } else if (d >= 1.0f) { - return p_segment[1]; // After first point. + return p_segment_b; // After first point. } else { - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } } +#ifndef DISABLE_DEPRECATED static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) { - Vector3 p = p_point - p_segment[0]; - Vector3 n = p_segment[1] - p_segment[0]; + return get_closest_point_to_segment_uncapped(p_point, p_segment[0], p_segment[1]); + } +#endif // DISABLE_DEPRECATED + + static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_segment_a, const Vector3 &p_segment_b) { + Vector3 p = p_point - p_segment_a; + Vector3 n = p_segment_b - p_segment_a; real_t l2 = n.length_squared(); if (l2 < 1e-20f) { - return p_segment[0]; // Both points are the same, just give any. + return p_segment_a; // Both points are the same, just give any. } real_t d = n.dot(p) / l2; - return p_segment[0] + n * d; // Inside. + return p_segment_a + n * d; // Inside. } static inline bool point_in_projected_triangle(const Vector3 &p_point, const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) { @@ -383,8 +393,14 @@ public: return true; } +#ifndef DISABLE_DEPRECATED static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { - real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]); + return triangle_sphere_intersection_test(p_triangle[0], p_triangle[1], p_triangle[2], p_normal, p_sphere_pos, p_sphere_radius, r_triangle_contact, r_sphere_contact); + } +#endif // DISABLE_DEPRECATED + + static inline bool triangle_sphere_intersection_test(const Vector3 &p_triangle_a, const Vector3 &p_triangle_b, const Vector3 &p_triangle_c, const Vector3 &p_normal, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 &r_triangle_contact, Vector3 &r_sphere_contact) { + real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle_a); if (d > p_sphere_radius || d < -p_sphere_radius) { // Not touching the plane of the face, return. @@ -395,7 +411,7 @@ public: /** 2nd) TEST INSIDE TRIANGLE **/ - if (Geometry3D::point_in_projected_triangle(contact, p_triangle[0], p_triangle[1], p_triangle[2])) { + if (Geometry3D::point_in_projected_triangle(contact, p_triangle_a, p_triangle_b, p_triangle_c)) { r_triangle_contact = contact; r_sphere_contact = p_sphere_pos - p_normal * p_sphere_radius; //printf("solved inside triangle\n"); @@ -404,7 +420,7 @@ public: /** 3rd TEST INSIDE EDGE CYLINDERS **/ - const Vector3 verts[4] = { p_triangle[0], p_triangle[1], p_triangle[2], p_triangle[0] }; // for() friendly + const Vector3 verts[4] = { p_triangle_a, p_triangle_b, p_triangle_c, p_triangle_a }; // for() friendly for (int i = 0; i < 3; i++) { // Check edge cylinder. @@ -420,7 +436,7 @@ public: real_t ad = axis.dot(n2); - if (ABS(ad) > p_sphere_radius) { + if (Math::abs(ad) > p_sphere_radius) { // No chance with this edge, too far away. continue; } @@ -468,7 +484,7 @@ public: LOC_OUTSIDE = -1 }; - if (polygon.size() == 0) { + if (polygon.is_empty()) { return polygon; } @@ -840,5 +856,3 @@ public: return n.normalized(); } }; - -#endif // GEOMETRY_3D_H diff --git a/engine/core/math/math_defs.h b/engine/core/math/math_defs.h index fe53121a..5a9be58c 100644 --- a/engine/core/math/math_defs.h +++ b/engine/core/math/math_defs.h @@ -28,8 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MATH_DEFS_H -#define MATH_DEFS_H +#pragma once + +#include "core/typedefs.h" + +#include + +namespace Math { +inline constexpr double SQRT2 = 1.4142135623730950488016887242; +inline constexpr double SQRT3 = 1.7320508075688772935274463415059; +inline constexpr double SQRT12 = 0.7071067811865475244008443621048490; +inline constexpr double SQRT13 = 0.57735026918962576450914878050196; +inline constexpr double LN2 = 0.6931471805599453094172321215; +inline constexpr double TAU = 6.2831853071795864769252867666; +inline constexpr double PI = 3.1415926535897932384626433833; +inline constexpr double E = 2.7182818284590452353602874714; +inline constexpr double INF = std::numeric_limits::infinity(); +inline constexpr double NaN = std::numeric_limits::quiet_NaN(); +} // namespace Math #define CMP_EPSILON 0.00001 #define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON) @@ -37,13 +53,6 @@ #define CMP_NORMALIZE_TOLERANCE 0.000001 #define CMP_POINT_IN_PLANE_EPSILON 0.00001 -#define Math_SQRT12 0.7071067811865475244008443621048490 -#define Math_SQRT2 1.4142135623730950488016887242 -#define Math_LN2 0.6931471805599453094172321215 -#define Math_TAU 6.2831853071795864769252867666 -#define Math_PI 3.1415926535897932384626433833 -#define Math_E 2.7182818284590452353602874714 - #ifdef DEBUG_ENABLED #define MATH_CHECKS #endif @@ -136,5 +145,3 @@ typedef double real_t; #else typedef float real_t; #endif - -#endif // MATH_DEFS_H diff --git a/engine/core/math/math_fieldwise.cpp b/engine/core/math/math_fieldwise.cpp index 4064e6aa..8e81e4cc 100644 --- a/engine/core/math/math_fieldwise.cpp +++ b/engine/core/math/math_fieldwise.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifdef TOOLS_ENABLED +#ifdef DEBUG_ENABLED #include "math_fieldwise.h" @@ -242,4 +242,4 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const /* clang-format on */ } -#endif // TOOLS_ENABLED +#endif // DEBUG_ENABLED diff --git a/engine/core/math/math_fieldwise.h b/engine/core/math/math_fieldwise.h index 6d222c15..2628beb4 100644 --- a/engine/core/math/math_fieldwise.h +++ b/engine/core/math/math_fieldwise.h @@ -28,15 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MATH_FIELDWISE_H -#define MATH_FIELDWISE_H +#pragma once -#ifdef TOOLS_ENABLED +#ifdef DEBUG_ENABLED #include "core/variant/variant.h" Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field); -#endif // TOOLS_ENABLED - -#endif // MATH_FIELDWISE_H +#endif // DEBUG_ENABLED diff --git a/engine/core/math/math_funcs.cpp b/engine/core/math/math_funcs.cpp index 0d5b0faa..76d9cd25 100644 --- a/engine/core/math/math_funcs.cpp +++ b/engine/core/math/math_funcs.cpp @@ -31,18 +31,19 @@ #include "math_funcs.h" #include "core/error/error_macros.h" +#include "core/math/random_pcg.h" -RandomPCG Math::default_rand(RandomPCG::DEFAULT_SEED, RandomPCG::DEFAULT_INC); +static RandomPCG default_rand; -uint32_t Math::rand_from_seed(uint64_t *seed) { - RandomPCG rng = RandomPCG(*seed, RandomPCG::DEFAULT_INC); +uint32_t Math::rand_from_seed(uint64_t *p_seed) { + RandomPCG rng = RandomPCG(*p_seed); uint32_t r = rng.rand(); - *seed = rng.get_seed(); + *p_seed = rng.get_seed(); return r; } -void Math::seed(uint64_t x) { - default_rand.seed(x); +void Math::seed(uint64_t p_value) { + default_rand.seed(p_value); } void Math::randomize() { @@ -53,8 +54,8 @@ uint32_t Math::rand() { return default_rand.rand(); } -double Math::randfn(double mean, double deviation) { - return default_rand.randfn(mean, deviation); +double Math::randfn(double p_mean, double p_deviation) { + return default_rand.randfn(p_mean, p_deviation); } int Math::step_decimals(double p_step) { @@ -168,14 +169,14 @@ uint32_t Math::larger_prime(uint32_t p_val) { } } -double Math::random(double from, double to) { - return default_rand.random(from, to); +double Math::random(double p_from, double p_to) { + return default_rand.random(p_from, p_to); } -float Math::random(float from, float to) { - return default_rand.random(from, to); +float Math::random(float p_from, float p_to) { + return default_rand.random(p_from, p_to); } -int Math::random(int from, int to) { - return default_rand.random(from, to); +int Math::random(int p_from, int p_to) { + return default_rand.random(p_from, p_to); } diff --git a/engine/core/math/math_funcs.h b/engine/core/math/math_funcs.h index 1afc5f4b..56027765 100644 --- a/engine/core/math/math_funcs.h +++ b/engine/core/math/math_funcs.h @@ -28,735 +28,851 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MATH_FUNCS_H -#define MATH_FUNCS_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_defs.h" -#include "core/math/random_pcg.h" #include "core/typedefs.h" -#include "thirdparty/misc/pcg.h" - #include #include -class Math { - static RandomPCG default_rand; +namespace Math { -public: - Math() {} // useless to instance +_ALWAYS_INLINE_ double sin(double p_x) { + return ::sin(p_x); +} +_ALWAYS_INLINE_ float sin(float p_x) { + return ::sinf(p_x); +} - // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD). - static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF; +_ALWAYS_INLINE_ double cos(double p_x) { + return ::cos(p_x); +} +_ALWAYS_INLINE_ float cos(float p_x) { + return ::cosf(p_x); +} - static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } - static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } +_ALWAYS_INLINE_ double tan(double p_x) { + return ::tan(p_x); +} +_ALWAYS_INLINE_ float tan(float p_x) { + return ::tanf(p_x); +} - static _ALWAYS_INLINE_ double cos(double p_x) { return ::cos(p_x); } - static _ALWAYS_INLINE_ float cos(float p_x) { return ::cosf(p_x); } +_ALWAYS_INLINE_ double sinh(double p_x) { + return ::sinh(p_x); +} +_ALWAYS_INLINE_ float sinh(float p_x) { + return ::sinhf(p_x); +} - static _ALWAYS_INLINE_ double tan(double p_x) { return ::tan(p_x); } - static _ALWAYS_INLINE_ float tan(float p_x) { return ::tanf(p_x); } +_ALWAYS_INLINE_ double sinc(double p_x) { + return p_x == 0 ? 1 : sin(p_x) / p_x; +} +_ALWAYS_INLINE_ float sinc(float p_x) { + return p_x == 0 ? 1 : sin(p_x) / p_x; +} - static _ALWAYS_INLINE_ double sinh(double p_x) { return ::sinh(p_x); } - static _ALWAYS_INLINE_ float sinh(float p_x) { return ::sinhf(p_x); } +_ALWAYS_INLINE_ double sincn(double p_x) { + return sinc(PI * p_x); +} +_ALWAYS_INLINE_ float sincn(float p_x) { + return sinc((float)PI * p_x); +} - static _ALWAYS_INLINE_ float sinc(float p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } - static _ALWAYS_INLINE_ double sinc(double p_x) { return p_x == 0 ? 1 : ::sin(p_x) / p_x; } +_ALWAYS_INLINE_ double cosh(double p_x) { + return ::cosh(p_x); +} +_ALWAYS_INLINE_ float cosh(float p_x) { + return ::coshf(p_x); +} - static _ALWAYS_INLINE_ float sincn(float p_x) { return sinc((float)Math_PI * p_x); } - static _ALWAYS_INLINE_ double sincn(double p_x) { return sinc(Math_PI * p_x); } +_ALWAYS_INLINE_ double tanh(double p_x) { + return ::tanh(p_x); +} +_ALWAYS_INLINE_ float tanh(float p_x) { + return ::tanhf(p_x); +} - static _ALWAYS_INLINE_ double cosh(double p_x) { return ::cosh(p_x); } - static _ALWAYS_INLINE_ float cosh(float p_x) { return ::coshf(p_x); } +// Always does clamping so always safe to use. +_ALWAYS_INLINE_ double asin(double p_x) { + return p_x < -1 ? (-PI / 2) : (p_x > 1 ? (PI / 2) : ::asin(p_x)); +} +_ALWAYS_INLINE_ float asin(float p_x) { + return p_x < -1 ? (-(float)PI / 2) : (p_x > 1 ? ((float)PI / 2) : ::asinf(p_x)); +} - static _ALWAYS_INLINE_ double tanh(double p_x) { return ::tanh(p_x); } - static _ALWAYS_INLINE_ float tanh(float p_x) { return ::tanhf(p_x); } +// Always does clamping so always safe to use. +_ALWAYS_INLINE_ double acos(double p_x) { + return p_x < -1 ? PI : (p_x > 1 ? 0 : ::acos(p_x)); +} +_ALWAYS_INLINE_ float acos(float p_x) { + return p_x < -1 ? (float)PI : (p_x > 1 ? 0 : ::acosf(p_x)); +} - // Always does clamping so always safe to use. - static _ALWAYS_INLINE_ double asin(double p_x) { return p_x < -1 ? (-Math_PI / 2) : (p_x > 1 ? (Math_PI / 2) : ::asin(p_x)); } - static _ALWAYS_INLINE_ float asin(float p_x) { return p_x < -1 ? (-Math_PI / 2) : (p_x > 1 ? (Math_PI / 2) : ::asinf(p_x)); } +_ALWAYS_INLINE_ double atan(double p_x) { + return ::atan(p_x); +} +_ALWAYS_INLINE_ float atan(float p_x) { + return ::atanf(p_x); +} - // Always does clamping so always safe to use. - static _ALWAYS_INLINE_ double acos(double p_x) { return p_x < -1 ? Math_PI : (p_x > 1 ? 0 : ::acos(p_x)); } - static _ALWAYS_INLINE_ float acos(float p_x) { return p_x < -1 ? Math_PI : (p_x > 1 ? 0 : ::acosf(p_x)); } +_ALWAYS_INLINE_ double atan2(double p_y, double p_x) { + return ::atan2(p_y, p_x); +} +_ALWAYS_INLINE_ float atan2(float p_y, float p_x) { + return ::atan2f(p_y, p_x); +} - static _ALWAYS_INLINE_ double atan(double p_x) { return ::atan(p_x); } - static _ALWAYS_INLINE_ float atan(float p_x) { return ::atanf(p_x); } +_ALWAYS_INLINE_ double asinh(double p_x) { + return ::asinh(p_x); +} +_ALWAYS_INLINE_ float asinh(float p_x) { + return ::asinhf(p_x); +} - static _ALWAYS_INLINE_ double atan2(double p_y, double p_x) { return ::atan2(p_y, p_x); } - static _ALWAYS_INLINE_ float atan2(float p_y, float p_x) { return ::atan2f(p_y, p_x); } +// Always does clamping so always safe to use. +_ALWAYS_INLINE_ double acosh(double p_x) { + return p_x < 1 ? 0 : ::acosh(p_x); +} +_ALWAYS_INLINE_ float acosh(float p_x) { + return p_x < 1 ? 0 : ::acoshf(p_x); +} - static _ALWAYS_INLINE_ double asinh(double p_x) { return ::asinh(p_x); } - static _ALWAYS_INLINE_ float asinh(float p_x) { return ::asinhf(p_x); } +// Always does clamping so always safe to use. +_ALWAYS_INLINE_ double atanh(double p_x) { + return p_x <= -1 ? -INF : (p_x >= 1 ? INF : ::atanh(p_x)); +} +_ALWAYS_INLINE_ float atanh(float p_x) { + return p_x <= -1 ? (float)-INF : (p_x >= 1 ? (float)INF : ::atanhf(p_x)); +} - // Always does clamping so always safe to use. - static _ALWAYS_INLINE_ double acosh(double p_x) { return p_x < 1 ? 0 : ::acosh(p_x); } - static _ALWAYS_INLINE_ float acosh(float p_x) { return p_x < 1 ? 0 : ::acoshf(p_x); } +_ALWAYS_INLINE_ double sqrt(double p_x) { + return ::sqrt(p_x); +} +_ALWAYS_INLINE_ float sqrt(float p_x) { + return ::sqrtf(p_x); +} - // Always does clamping so always safe to use. - static _ALWAYS_INLINE_ double atanh(double p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanh(p_x)); } - static _ALWAYS_INLINE_ float atanh(float p_x) { return p_x <= -1 ? -INFINITY : (p_x >= 1 ? INFINITY : ::atanhf(p_x)); } +_ALWAYS_INLINE_ double fmod(double p_x, double p_y) { + return ::fmod(p_x, p_y); +} +_ALWAYS_INLINE_ float fmod(float p_x, float p_y) { + return ::fmodf(p_x, p_y); +} - static _ALWAYS_INLINE_ double sqrt(double p_x) { return ::sqrt(p_x); } - static _ALWAYS_INLINE_ float sqrt(float p_x) { return ::sqrtf(p_x); } +_ALWAYS_INLINE_ double modf(double p_x, double *r_y) { + return ::modf(p_x, r_y); +} +_ALWAYS_INLINE_ float modf(float p_x, float *r_y) { + return ::modff(p_x, r_y); +} - static _ALWAYS_INLINE_ double fmod(double p_x, double p_y) { return ::fmod(p_x, p_y); } - static _ALWAYS_INLINE_ float fmod(float p_x, float p_y) { return ::fmodf(p_x, p_y); } +_ALWAYS_INLINE_ double floor(double p_x) { + return ::floor(p_x); +} +_ALWAYS_INLINE_ float floor(float p_x) { + return ::floorf(p_x); +} - static _ALWAYS_INLINE_ double modf(double p_x, double *r_y) { return ::modf(p_x, r_y); } - static _ALWAYS_INLINE_ float modf(float p_x, float *r_y) { return ::modff(p_x, r_y); } +_ALWAYS_INLINE_ double ceil(double p_x) { + return ::ceil(p_x); +} +_ALWAYS_INLINE_ float ceil(float p_x) { + return ::ceilf(p_x); +} - static _ALWAYS_INLINE_ double floor(double p_x) { return ::floor(p_x); } - static _ALWAYS_INLINE_ float floor(float p_x) { return ::floorf(p_x); } +_ALWAYS_INLINE_ double pow(double p_x, double p_y) { + return ::pow(p_x, p_y); +} +_ALWAYS_INLINE_ float pow(float p_x, float p_y) { + return ::powf(p_x, p_y); +} - static _ALWAYS_INLINE_ double ceil(double p_x) { return ::ceil(p_x); } - static _ALWAYS_INLINE_ float ceil(float p_x) { return ::ceilf(p_x); } +_ALWAYS_INLINE_ double log(double p_x) { + return ::log(p_x); +} +_ALWAYS_INLINE_ float log(float p_x) { + return ::logf(p_x); +} - static _ALWAYS_INLINE_ double pow(double p_x, double p_y) { return ::pow(p_x, p_y); } - static _ALWAYS_INLINE_ float pow(float p_x, float p_y) { return ::powf(p_x, p_y); } +_ALWAYS_INLINE_ double log1p(double p_x) { + return ::log1p(p_x); +} +_ALWAYS_INLINE_ float log1p(float p_x) { + return ::log1pf(p_x); +} - static _ALWAYS_INLINE_ double log(double p_x) { return ::log(p_x); } - static _ALWAYS_INLINE_ float log(float p_x) { return ::logf(p_x); } +_ALWAYS_INLINE_ double log2(double p_x) { + return ::log2(p_x); +} +_ALWAYS_INLINE_ float log2(float p_x) { + return ::log2f(p_x); +} - static _ALWAYS_INLINE_ double log1p(double p_x) { return ::log1p(p_x); } - static _ALWAYS_INLINE_ float log1p(float p_x) { return ::log1pf(p_x); } +_ALWAYS_INLINE_ double exp(double p_x) { + return ::exp(p_x); +} +_ALWAYS_INLINE_ float exp(float p_x) { + return ::expf(p_x); +} - static _ALWAYS_INLINE_ double log2(double p_x) { return ::log2(p_x); } - static _ALWAYS_INLINE_ float log2(float p_x) { return ::log2f(p_x); } - - static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); } - static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); } - - static _ALWAYS_INLINE_ bool is_nan(double p_val) { +_ALWAYS_INLINE_ bool is_nan(double p_val) { #ifdef _MSC_VER - return _isnan(p_val); + return _isnan(p_val); #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint64_t u; - double f; - } ieee754; - ieee754.f = p_val; - // (unsigned)(0x7ff0000000000001 >> 32) : 0x7ff00000 - return ((((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0)) > 0x7ff00000); + union { + uint64_t u; + double f; + } ieee754; + ieee754.f = p_val; + // (unsigned)(0x7ff0000000000001 >> 32) : 0x7ff00000 + return ((((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0)) > 0x7ff00000); #else - return isnan(p_val); + return isnan(p_val); #endif - } +} - static _ALWAYS_INLINE_ bool is_nan(float p_val) { +_ALWAYS_INLINE_ bool is_nan(float p_val) { #ifdef _MSC_VER - return _isnan(p_val); + return _isnan(p_val); #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint32_t u; - float f; - } ieee754; - ieee754.f = p_val; - // ----------------------------------- - // (single-precision floating-point) - // NaN : s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx - // : (> 0x7f800000) - // where, - // s : sign - // x : non-zero number - // ----------------------------------- - return ((ieee754.u & 0x7fffffff) > 0x7f800000); + union { + uint32_t u; + float f; + } ieee754; + ieee754.f = p_val; + // ----------------------------------- + // (single-precision floating-point) + // NaN : s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx + // : (> 0x7f800000) + // where, + // s : sign + // x : non-zero number + // ----------------------------------- + return ((ieee754.u & 0x7fffffff) > 0x7f800000); #else - return isnan(p_val); + return isnan(p_val); #endif - } +} - static _ALWAYS_INLINE_ bool is_inf(double p_val) { +_ALWAYS_INLINE_ bool is_inf(double p_val) { #ifdef _MSC_VER - return !_finite(p_val); + return !_finite(p_val); // use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint64_t u; - double f; - } ieee754; - ieee754.f = p_val; - return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && - ((unsigned)ieee754.u == 0); + union { + uint64_t u; + double f; + } ieee754; + ieee754.f = p_val; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + ((unsigned)ieee754.u == 0); #else - return isinf(p_val); + return isinf(p_val); #endif - } +} - static _ALWAYS_INLINE_ bool is_inf(float p_val) { +_ALWAYS_INLINE_ bool is_inf(float p_val) { #ifdef _MSC_VER - return !_finite(p_val); + return !_finite(p_val); // use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era #elif defined(__GNUC__) && __GNUC__ < 6 - union { - uint32_t u; - float f; - } ieee754; - ieee754.f = p_val; - return (ieee754.u & 0x7fffffff) == 0x7f800000; + union { + uint32_t u; + float f; + } ieee754; + ieee754.f = p_val; + return (ieee754.u & 0x7fffffff) == 0x7f800000; #else - return isinf(p_val); + return isinf(p_val); #endif +} + +// These methods assume (p_num + p_den) doesn't overflow. +_ALWAYS_INLINE_ int32_t division_round_up(int32_t p_num, int32_t p_den) { + int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; + return (p_num + p_den + offset) / p_den; +} +_ALWAYS_INLINE_ uint32_t division_round_up(uint32_t p_num, uint32_t p_den) { + return (p_num + p_den - 1) / p_den; +} +_ALWAYS_INLINE_ int64_t division_round_up(int64_t p_num, int64_t p_den) { + int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; + return (p_num + p_den + offset) / p_den; +} +_ALWAYS_INLINE_ uint64_t division_round_up(uint64_t p_num, uint64_t p_den) { + return (p_num + p_den - 1) / p_den; +} + +_ALWAYS_INLINE_ bool is_finite(double p_val) { + return isfinite(p_val); +} +_ALWAYS_INLINE_ bool is_finite(float p_val) { + return isfinite(p_val); +} + +_ALWAYS_INLINE_ double absd(double p_value) { + return ::fabs(p_value); +} +_ALWAYS_INLINE_ float absf(float p_value) { + return ::fabsf(p_value); +} + +_ALWAYS_INLINE_ double abs(double p_value) { + return absd(p_value); +} +_ALWAYS_INLINE_ float abs(float p_value) { + return absf(p_value); +} +_ALWAYS_INLINE_ int8_t abs(int8_t p_value) { + return p_value > 0 ? p_value : -p_value; +} +_ALWAYS_INLINE_ int16_t abs(int16_t p_value) { + return p_value > 0 ? p_value : -p_value; +} +_ALWAYS_INLINE_ int32_t abs(int32_t p_value) { + return ::abs(p_value); +} +_ALWAYS_INLINE_ int64_t abs(int64_t p_value) { + return ::llabs(p_value); +} + +_ALWAYS_INLINE_ double fposmod(double p_x, double p_y) { + double value = fmod(p_x, p_y); + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; } - - // These methods assume (p_num + p_den) doesn't overflow. - static _ALWAYS_INLINE_ int32_t division_round_up(int32_t p_num, int32_t p_den) { - int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; - return (p_num + p_den + offset) / p_den; + value += 0.0; + return value; +} +_ALWAYS_INLINE_ float fposmod(float p_x, float p_y) { + float value = fmod(p_x, p_y); + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; } - static _ALWAYS_INLINE_ uint32_t division_round_up(uint32_t p_num, uint32_t p_den) { - return (p_num + p_den - 1) / p_den; + value += 0.0f; + return value; +} + +_ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) { + double value = fmod(p_x, p_y); + if (value < 0) { + value += p_y; } - static _ALWAYS_INLINE_ int64_t division_round_up(int64_t p_num, int64_t p_den) { - int32_t offset = (p_num < 0 && p_den < 0) ? 1 : -1; - return (p_num + p_den + offset) / p_den; + value += 0.0; + return value; +} +_ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) { + float value = fmod(p_x, p_y); + if (value < 0) { + value += p_y; } - static _ALWAYS_INLINE_ uint64_t division_round_up(uint64_t p_num, uint64_t p_den) { - return (p_num + p_den - 1) / p_den; + value += 0.0f; + return value; +} + +_ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) { + ERR_FAIL_COND_V_MSG(p_y == 0, 0, "Division by zero in posmod is undefined. Returning 0 as fallback."); + int64_t value = p_x % p_y; + if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { + value += p_y; } + return value; +} - static _ALWAYS_INLINE_ bool is_finite(double p_val) { return isfinite(p_val); } - static _ALWAYS_INLINE_ bool is_finite(float p_val) { return isfinite(p_val); } +_ALWAYS_INLINE_ double deg_to_rad(double p_y) { + return p_y * (PI / 180.0); +} +_ALWAYS_INLINE_ float deg_to_rad(float p_y) { + return p_y * ((float)PI / 180.0f); +} - static _ALWAYS_INLINE_ double abs(double g) { return absd(g); } - static _ALWAYS_INLINE_ float abs(float g) { return absf(g); } - static _ALWAYS_INLINE_ int abs(int g) { return g > 0 ? g : -g; } +_ALWAYS_INLINE_ double rad_to_deg(double p_y) { + return p_y * (180.0 / PI); +} +_ALWAYS_INLINE_ float rad_to_deg(float p_y) { + return p_y * (180.0f / (float)PI); +} - static _ALWAYS_INLINE_ double fposmod(double p_x, double p_y) { - double value = Math::fmod(p_x, p_y); - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; - } - value += 0.0; - return value; +_ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { + return p_from + (p_to - p_from) * p_weight; +} +_ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { + return p_from + (p_to - p_from) * p_weight; +} + +_ALWAYS_INLINE_ double cubic_interpolate(double p_from, double p_to, double p_pre, double p_post, double p_weight) { + return 0.5 * + ((p_from * 2.0) + + (-p_pre + p_to) * p_weight + + (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); +} +_ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { + return 0.5f * + ((p_from * 2.0f) + + (-p_pre + p_to) * p_weight + + (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + + (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); +} + +_ALWAYS_INLINE_ double cubic_interpolate_angle(double p_from, double p_to, double p_pre, double p_post, double p_weight) { + double from_rot = fmod(p_from, TAU); + + double pre_diff = fmod(p_pre - from_rot, TAU); + double pre_rot = from_rot + fmod(2.0 * pre_diff, TAU) - pre_diff; + + double to_diff = fmod(p_to - from_rot, TAU); + double to_rot = from_rot + fmod(2.0 * to_diff, TAU) - to_diff; + + double post_diff = fmod(p_post - to_rot, TAU); + double post_rot = to_rot + fmod(2.0 * post_diff, TAU) - post_diff; + + return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); +} + +_ALWAYS_INLINE_ float cubic_interpolate_angle(float p_from, float p_to, float p_pre, float p_post, float p_weight) { + float from_rot = fmod(p_from, (float)TAU); + + float pre_diff = fmod(p_pre - from_rot, (float)TAU); + float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)TAU) - pre_diff; + + float to_diff = fmod(p_to - from_rot, (float)TAU); + float to_rot = from_rot + fmod(2.0f * to_diff, (float)TAU) - to_diff; + + float post_diff = fmod(p_post - to_rot, (float)TAU); + float post_rot = to_rot + fmod(2.0f * post_diff, (float)TAU) - post_diff; + + return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); +} + +_ALWAYS_INLINE_ double cubic_interpolate_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, + double p_to_t, double p_pre_t, double p_post_t) { + /* Barry-Goldman method */ + double t = lerp(0.0, p_to_t, p_weight); + double a1 = lerp(p_pre, p_from, p_pre_t == 0 ? 0.0 : (t - p_pre_t) / -p_pre_t); + double a2 = lerp(p_from, p_to, p_to_t == 0 ? 0.5 : t / p_to_t); + double a3 = lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0 : (t - p_to_t) / (p_post_t - p_to_t)); + double b1 = lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0 : (t - p_pre_t) / (p_to_t - p_pre_t)); + double b2 = lerp(a2, a3, p_post_t == 0 ? 1.0 : t / p_post_t); + return lerp(b1, b2, p_to_t == 0 ? 0.5 : t / p_to_t); +} +_ALWAYS_INLINE_ float cubic_interpolate_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, + float p_to_t, float p_pre_t, float p_post_t) { + /* Barry-Goldman method */ + float t = lerp(0.0f, p_to_t, p_weight); + float a1 = lerp(p_pre, p_from, p_pre_t == 0 ? 0.0f : (t - p_pre_t) / -p_pre_t); + float a2 = lerp(p_from, p_to, p_to_t == 0 ? 0.5f : t / p_to_t); + float a3 = lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0f : (t - p_to_t) / (p_post_t - p_to_t)); + float b1 = lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0f : (t - p_pre_t) / (p_to_t - p_pre_t)); + float b2 = lerp(a2, a3, p_post_t == 0 ? 1.0f : t / p_post_t); + return lerp(b1, b2, p_to_t == 0 ? 0.5f : t / p_to_t); +} + +_ALWAYS_INLINE_ double cubic_interpolate_angle_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, + double p_to_t, double p_pre_t, double p_post_t) { + double from_rot = fmod(p_from, TAU); + + double pre_diff = fmod(p_pre - from_rot, TAU); + double pre_rot = from_rot + fmod(2.0 * pre_diff, TAU) - pre_diff; + + double to_diff = fmod(p_to - from_rot, TAU); + double to_rot = from_rot + fmod(2.0 * to_diff, TAU) - to_diff; + + double post_diff = fmod(p_post - to_rot, TAU); + double post_rot = to_rot + fmod(2.0 * post_diff, TAU) - post_diff; + + return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); +} +_ALWAYS_INLINE_ float cubic_interpolate_angle_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, + float p_to_t, float p_pre_t, float p_post_t) { + float from_rot = fmod(p_from, (float)TAU); + + float pre_diff = fmod(p_pre - from_rot, (float)TAU); + float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)TAU) - pre_diff; + + float to_diff = fmod(p_to - from_rot, (float)TAU); + float to_rot = from_rot + fmod(2.0f * to_diff, (float)TAU) - to_diff; + + float post_diff = fmod(p_post - to_rot, (float)TAU); + float post_rot = to_rot + fmod(2.0f * post_diff, (float)TAU) - post_diff; + + return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); +} + +_ALWAYS_INLINE_ double bezier_interpolate(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + double omt = (1.0 - p_t); + double omt2 = omt * omt; + double omt3 = omt2 * omt; + double t2 = p_t * p_t; + double t3 = t2 * p_t; + + return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; +} +_ALWAYS_INLINE_ float bezier_interpolate(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + float omt = (1.0f - p_t); + float omt2 = omt * omt; + float omt3 = omt2 * omt; + float t2 = p_t * p_t; + float t3 = t2 * p_t; + + return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0f + p_control_2 * omt * t2 * 3.0f + p_end * t3; +} + +_ALWAYS_INLINE_ double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + double omt = (1.0 - p_t); + double omt2 = omt * omt; + double t2 = p_t * p_t; + + double d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; + return d; +} +_ALWAYS_INLINE_ float bezier_derivative(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { + /* Formula from Wikipedia article on Bezier curves. */ + float omt = (1.0f - p_t); + float omt2 = omt * omt; + float t2 = p_t * p_t; + + float d = (p_control_1 - p_start) * 3.0f * omt2 + (p_control_2 - p_control_1) * 6.0f * omt * p_t + (p_end - p_control_2) * 3.0f * t2; + return d; +} + +_ALWAYS_INLINE_ double angle_difference(double p_from, double p_to) { + double difference = fmod(p_to - p_from, TAU); + return fmod(2.0 * difference, TAU) - difference; +} +_ALWAYS_INLINE_ float angle_difference(float p_from, float p_to) { + float difference = fmod(p_to - p_from, (float)TAU); + return fmod(2.0f * difference, (float)TAU) - difference; +} + +_ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { + return p_from + angle_difference(p_from, p_to) * p_weight; +} +_ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { + return p_from + angle_difference(p_from, p_to) * p_weight; +} + +_ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { + return (p_value - p_from) / (p_to - p_from); +} +_ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { + return (p_value - p_from) / (p_to - p_from); +} + +_ALWAYS_INLINE_ double remap(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { + return lerp(p_ostart, p_ostop, inverse_lerp(p_istart, p_istop, p_value)); +} +_ALWAYS_INLINE_ float remap(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { + return lerp(p_ostart, p_ostop, inverse_lerp(p_istart, p_istop, p_value)); +} + +_ALWAYS_INLINE_ bool is_equal_approx(double p_left, double p_right, double p_tolerance) { + // Check for exact equality first, required to handle "infinity" values. + if (p_left == p_right) { + return true; } - static _ALWAYS_INLINE_ float fposmod(float p_x, float p_y) { - float value = Math::fmod(p_x, p_y); - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; - } - value += 0.0f; - return value; + // Then check for approximate equality. + return abs(p_left - p_right) < p_tolerance; +} +_ALWAYS_INLINE_ bool is_equal_approx(float p_left, float p_right, float p_tolerance) { + // Check for exact equality first, required to handle "infinity" values. + if (p_left == p_right) { + return true; } - static _ALWAYS_INLINE_ float fposmodp(float p_x, float p_y) { - float value = Math::fmod(p_x, p_y); - if (value < 0) { - value += p_y; - } - value += 0.0f; - return value; + // Then check for approximate equality. + return abs(p_left - p_right) < p_tolerance; +} + +_ALWAYS_INLINE_ bool is_equal_approx(double p_left, double p_right) { + // Check for exact equality first, required to handle "infinity" values. + if (p_left == p_right) { + return true; } - static _ALWAYS_INLINE_ double fposmodp(double p_x, double p_y) { - double value = Math::fmod(p_x, p_y); - if (value < 0) { - value += p_y; - } - value += 0.0; - return value; + // Then check for approximate equality. + double tolerance = CMP_EPSILON * abs(p_left); + if (tolerance < CMP_EPSILON) { + tolerance = CMP_EPSILON; } - - static _ALWAYS_INLINE_ int64_t posmod(int64_t p_x, int64_t p_y) { - ERR_FAIL_COND_V_MSG(p_y == 0, 0, "Division by zero in posmod is undefined. Returning 0 as fallback."); - int64_t value = p_x % p_y; - if (((value < 0) && (p_y > 0)) || ((value > 0) && (p_y < 0))) { - value += p_y; - } - return value; + return abs(p_left - p_right) < tolerance; +} +_ALWAYS_INLINE_ bool is_equal_approx(float p_left, float p_right) { + // Check for exact equality first, required to handle "infinity" values. + if (p_left == p_right) { + return true; } - - static _ALWAYS_INLINE_ double deg_to_rad(double p_y) { return p_y * (Math_PI / 180.0); } - static _ALWAYS_INLINE_ float deg_to_rad(float p_y) { return p_y * (float)(Math_PI / 180.0); } - - static _ALWAYS_INLINE_ double rad_to_deg(double p_y) { return p_y * (180.0 / Math_PI); } - static _ALWAYS_INLINE_ float rad_to_deg(float p_y) { return p_y * (float)(180.0 / Math_PI); } - - static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } - static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } - - static _ALWAYS_INLINE_ double cubic_interpolate(double p_from, double p_to, double p_pre, double p_post, double p_weight) { - return 0.5 * - ((p_from * 2.0) + - (-p_pre + p_to) * p_weight + - (2.0 * p_pre - 5.0 * p_from + 4.0 * p_to - p_post) * (p_weight * p_weight) + - (-p_pre + 3.0 * p_from - 3.0 * p_to + p_post) * (p_weight * p_weight * p_weight)); + // Then check for approximate equality. + float tolerance = (float)CMP_EPSILON * abs(p_left); + if (tolerance < (float)CMP_EPSILON) { + tolerance = (float)CMP_EPSILON; } - static _ALWAYS_INLINE_ float cubic_interpolate(float p_from, float p_to, float p_pre, float p_post, float p_weight) { - return 0.5f * - ((p_from * 2.0f) + - (-p_pre + p_to) * p_weight + - (2.0f * p_pre - 5.0f * p_from + 4.0f * p_to - p_post) * (p_weight * p_weight) + - (-p_pre + 3.0f * p_from - 3.0f * p_to + p_post) * (p_weight * p_weight * p_weight)); - } - - static _ALWAYS_INLINE_ double cubic_interpolate_angle(double p_from, double p_to, double p_pre, double p_post, double p_weight) { - double from_rot = fmod(p_from, Math_TAU); - - double pre_diff = fmod(p_pre - from_rot, Math_TAU); - double pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; - - double to_diff = fmod(p_to - from_rot, Math_TAU); - double to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; - - double post_diff = fmod(p_post - to_rot, Math_TAU); - double post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; - - return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); - } - - static _ALWAYS_INLINE_ float cubic_interpolate_angle(float p_from, float p_to, float p_pre, float p_post, float p_weight) { - float from_rot = fmod(p_from, (float)Math_TAU); - - float pre_diff = fmod(p_pre - from_rot, (float)Math_TAU); - float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)Math_TAU) - pre_diff; - - float to_diff = fmod(p_to - from_rot, (float)Math_TAU); - float to_rot = from_rot + fmod(2.0f * to_diff, (float)Math_TAU) - to_diff; - - float post_diff = fmod(p_post - to_rot, (float)Math_TAU); - float post_rot = to_rot + fmod(2.0f * post_diff, (float)Math_TAU) - post_diff; - - return cubic_interpolate(from_rot, to_rot, pre_rot, post_rot, p_weight); - } - - static _ALWAYS_INLINE_ double cubic_interpolate_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, - double p_to_t, double p_pre_t, double p_post_t) { - /* Barry-Goldman method */ - double t = Math::lerp(0.0, p_to_t, p_weight); - double a1 = Math::lerp(p_pre, p_from, p_pre_t == 0 ? 0.0 : (t - p_pre_t) / -p_pre_t); - double a2 = Math::lerp(p_from, p_to, p_to_t == 0 ? 0.5 : t / p_to_t); - double a3 = Math::lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0 : (t - p_to_t) / (p_post_t - p_to_t)); - double b1 = Math::lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0 : (t - p_pre_t) / (p_to_t - p_pre_t)); - double b2 = Math::lerp(a2, a3, p_post_t == 0 ? 1.0 : t / p_post_t); - return Math::lerp(b1, b2, p_to_t == 0 ? 0.5 : t / p_to_t); - } - - static _ALWAYS_INLINE_ float cubic_interpolate_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, - float p_to_t, float p_pre_t, float p_post_t) { - /* Barry-Goldman method */ - float t = Math::lerp(0.0f, p_to_t, p_weight); - float a1 = Math::lerp(p_pre, p_from, p_pre_t == 0 ? 0.0f : (t - p_pre_t) / -p_pre_t); - float a2 = Math::lerp(p_from, p_to, p_to_t == 0 ? 0.5f : t / p_to_t); - float a3 = Math::lerp(p_to, p_post, p_post_t - p_to_t == 0 ? 1.0f : (t - p_to_t) / (p_post_t - p_to_t)); - float b1 = Math::lerp(a1, a2, p_to_t - p_pre_t == 0 ? 0.0f : (t - p_pre_t) / (p_to_t - p_pre_t)); - float b2 = Math::lerp(a2, a3, p_post_t == 0 ? 1.0f : t / p_post_t); - return Math::lerp(b1, b2, p_to_t == 0 ? 0.5f : t / p_to_t); - } - - static _ALWAYS_INLINE_ double cubic_interpolate_angle_in_time(double p_from, double p_to, double p_pre, double p_post, double p_weight, - double p_to_t, double p_pre_t, double p_post_t) { - double from_rot = fmod(p_from, Math_TAU); - - double pre_diff = fmod(p_pre - from_rot, Math_TAU); - double pre_rot = from_rot + fmod(2.0 * pre_diff, Math_TAU) - pre_diff; - - double to_diff = fmod(p_to - from_rot, Math_TAU); - double to_rot = from_rot + fmod(2.0 * to_diff, Math_TAU) - to_diff; - - double post_diff = fmod(p_post - to_rot, Math_TAU); - double post_rot = to_rot + fmod(2.0 * post_diff, Math_TAU) - post_diff; - - return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); - } - - static _ALWAYS_INLINE_ float cubic_interpolate_angle_in_time(float p_from, float p_to, float p_pre, float p_post, float p_weight, - float p_to_t, float p_pre_t, float p_post_t) { - float from_rot = fmod(p_from, (float)Math_TAU); - - float pre_diff = fmod(p_pre - from_rot, (float)Math_TAU); - float pre_rot = from_rot + fmod(2.0f * pre_diff, (float)Math_TAU) - pre_diff; - - float to_diff = fmod(p_to - from_rot, (float)Math_TAU); - float to_rot = from_rot + fmod(2.0f * to_diff, (float)Math_TAU) - to_diff; - - float post_diff = fmod(p_post - to_rot, (float)Math_TAU); - float post_rot = to_rot + fmod(2.0f * post_diff, (float)Math_TAU) - post_diff; - - return cubic_interpolate_in_time(from_rot, to_rot, pre_rot, post_rot, p_weight, p_to_t, p_pre_t, p_post_t); - } - - static _ALWAYS_INLINE_ double bezier_interpolate(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - double omt = (1.0 - p_t); - double omt2 = omt * omt; - double omt3 = omt2 * omt; - double t2 = p_t * p_t; - double t3 = t2 * p_t; - - return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3; - } - - static _ALWAYS_INLINE_ float bezier_interpolate(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - float omt = (1.0f - p_t); - float omt2 = omt * omt; - float omt3 = omt2 * omt; - float t2 = p_t * p_t; - float t3 = t2 * p_t; - - return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0f + p_control_2 * omt * t2 * 3.0f + p_end * t3; - } - - static _ALWAYS_INLINE_ double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - double omt = (1.0 - p_t); - double omt2 = omt * omt; - double t2 = p_t * p_t; - - double d = (p_control_1 - p_start) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2; - return d; - } - - static _ALWAYS_INLINE_ float bezier_derivative(float p_start, float p_control_1, float p_control_2, float p_end, float p_t) { - /* Formula from Wikipedia article on Bezier curves. */ - float omt = (1.0f - p_t); - float omt2 = omt * omt; - float t2 = p_t * p_t; - - float d = (p_control_1 - p_start) * 3.0f * omt2 + (p_control_2 - p_control_1) * 6.0f * omt * p_t + (p_end - p_control_2) * 3.0f * t2; - return d; - } - - static _ALWAYS_INLINE_ double angle_difference(double p_from, double p_to) { - double difference = fmod(p_to - p_from, Math_TAU); - return fmod(2.0 * difference, Math_TAU) - difference; - } - static _ALWAYS_INLINE_ float angle_difference(float p_from, float p_to) { - float difference = fmod(p_to - p_from, (float)Math_TAU); - return fmod(2.0f * difference, (float)Math_TAU) - difference; - } - - static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) { - return p_from + Math::angle_difference(p_from, p_to) * p_weight; - } - static _ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) { - return p_from + Math::angle_difference(p_from, p_to) * p_weight; - } - - static _ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { - return (p_value - p_from) / (p_to - p_from); - } - static _ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { - return (p_value - p_from) / (p_to - p_from); - } - - static _ALWAYS_INLINE_ double remap(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { - return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); - } - static _ALWAYS_INLINE_ float remap(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { - return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); - } - - static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { - if (is_equal_approx(p_from, p_to)) { - if (likely(p_from <= p_to)) { - return p_s <= p_from ? 0.0 : 1.0; - } else { - return p_s <= p_to ? 1.0 : 0.0; - } - } - double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); - return s * s * (3.0 - 2.0 * s); - } - static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { - if (is_equal_approx(p_from, p_to)) { - if (likely(p_from <= p_to)) { - return p_s <= p_from ? 0.0f : 1.0f; - } else { - return p_s <= p_to ? 1.0f : 0.0f; - } - } - float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); - return s * s * (3.0f - 2.0f * s); - } - - static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { - return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; - } - static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { - return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; - } - - static _ALWAYS_INLINE_ double rotate_toward(double p_from, double p_to, double p_delta) { - double difference = Math::angle_difference(p_from, p_to); - double abs_difference = Math::abs(difference); - // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). - return p_from + CLAMP(p_delta, abs_difference - Math_PI, abs_difference) * (difference >= 0.0 ? 1.0 : -1.0); - } - static _ALWAYS_INLINE_ float rotate_toward(float p_from, float p_to, float p_delta) { - float difference = Math::angle_difference(p_from, p_to); - float abs_difference = Math::abs(difference); - // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). - return p_from + CLAMP(p_delta, abs_difference - (float)Math_PI, abs_difference) * (difference >= 0.0f ? 1.0f : -1.0f); - } - - static _ALWAYS_INLINE_ double linear_to_db(double p_linear) { - return Math::log(p_linear) * 8.6858896380650365530225783783321; - } - static _ALWAYS_INLINE_ float linear_to_db(float p_linear) { - return Math::log(p_linear) * (float)8.6858896380650365530225783783321; - } - - static _ALWAYS_INLINE_ double db_to_linear(double p_db) { - return Math::exp(p_db * 0.11512925464970228420089957273422); - } - static _ALWAYS_INLINE_ float db_to_linear(float p_db) { - return Math::exp(p_db * (float)0.11512925464970228420089957273422); - } - - static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); } - static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); } - - static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { - int64_t range = max - min; - return range == 0 ? min : min + ((((value - min) % range) + range) % range); - } - static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { - double range = max - min; - if (is_zero_approx(range)) { - return min; - } - double result = value - (range * Math::floor((value - min) / range)); - if (is_equal_approx(result, max)) { - return min; - } - return result; - } - static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) { - float range = max - min; - if (is_zero_approx(range)) { - return min; - } - float result = value - (range * Math::floor((value - min) / range)); - if (is_equal_approx(result, max)) { - return min; - } - return result; - } - - static _ALWAYS_INLINE_ float fract(float value) { - return value - floor(value); - } - static _ALWAYS_INLINE_ double fract(double value) { - return value - floor(value); - } - static _ALWAYS_INLINE_ float pingpong(float value, float length) { - return (length != 0.0f) ? abs(fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f; - } - static _ALWAYS_INLINE_ double pingpong(double value, double length) { - return (length != 0.0) ? abs(fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0; - } - - // double only, as these functions are mainly used by the editor and not performance-critical, - static double ease(double p_x, double p_c); - static int step_decimals(double p_step); - static int range_step_decimals(double p_step); // For editor use only. - static double snapped(double p_value, double p_step); - - static uint32_t larger_prime(uint32_t p_val); - - static void seed(uint64_t x); - static void randomize(); - static uint32_t rand_from_seed(uint64_t *seed); - static uint32_t rand(); - static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; } - static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; } - static double randfn(double mean, double deviation); - - static double random(double from, double to); - static float random(float from, float to); - static int random(int from, int to); - - static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b) { - // Check for exact equality first, required to handle "infinity" values. - if (a == b) { - return true; - } - // Then check for approximate equality. - float tolerance = (float)CMP_EPSILON * abs(a); - if (tolerance < (float)CMP_EPSILON) { - tolerance = (float)CMP_EPSILON; - } - return abs(a - b) < tolerance; - } - - static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b, float tolerance) { - // Check for exact equality first, required to handle "infinity" values. - if (a == b) { - return true; - } - // Then check for approximate equality. - return abs(a - b) < tolerance; - } - - static _ALWAYS_INLINE_ bool is_zero_approx(float s) { - return abs(s) < (float)CMP_EPSILON; - } - - static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b) { - // Check for exact equality first, required to handle "infinity" values. - if (a == b) { - return true; - } - // Then check for approximate equality. - double tolerance = CMP_EPSILON * abs(a); - if (tolerance < CMP_EPSILON) { - tolerance = CMP_EPSILON; - } - return abs(a - b) < tolerance; - } - - static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b, double tolerance) { - // Check for exact equality first, required to handle "infinity" values. - if (a == b) { - return true; - } - // Then check for approximate equality. - return abs(a - b) < tolerance; - } - - static _ALWAYS_INLINE_ bool is_zero_approx(double s) { - return abs(s) < CMP_EPSILON; - } - - static _ALWAYS_INLINE_ float absf(float g) { - union { - float f; - uint32_t i; - } u; - - u.f = g; - u.i &= 2147483647u; - return u.f; - } - - static _ALWAYS_INLINE_ double absd(double g) { - union { - double d; - uint64_t i; - } u; - u.d = g; - u.i &= (uint64_t)9223372036854775807ll; - return u.d; - } - - // This function should be as fast as possible and rounding mode should not matter. - static _ALWAYS_INLINE_ int fast_ftoi(float a) { - // Assuming every supported compiler has `lrint()`. - return lrintf(a); - } - - static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) { - uint16_t h_exp, h_sig; - uint32_t f_sgn, f_exp, f_sig; - - h_exp = (h & 0x7c00u); - f_sgn = ((uint32_t)h & 0x8000u) << 16; - switch (h_exp) { - case 0x0000u: /* 0 or subnormal */ - h_sig = (h & 0x03ffu); - /* Signed zero */ - if (h_sig == 0) { - return f_sgn; - } - /* Subnormal */ - h_sig <<= 1; - while ((h_sig & 0x0400u) == 0) { - h_sig <<= 1; - h_exp++; - } - f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23; - f_sig = ((uint32_t)(h_sig & 0x03ffu)) << 13; - return f_sgn + f_exp + f_sig; - case 0x7c00u: /* inf or NaN */ - /* All-ones exponent and a copy of the significand */ - return f_sgn + 0x7f800000u + (((uint32_t)(h & 0x03ffu)) << 13); - default: /* normalized */ - /* Just need to adjust the exponent and shift */ - return f_sgn + (((uint32_t)(h & 0x7fffu) + 0x1c000u) << 13); - } - } - - static _ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *h) { - union { - uint32_t u32; - float f32; - } u; - - u.u32 = halfbits_to_floatbits(*h); - return u.f32; - } - - static _ALWAYS_INLINE_ float half_to_float(const uint16_t h) { - return halfptr_to_float(&h); - } - - static _ALWAYS_INLINE_ uint16_t make_half_float(float f) { - union { - float fv; - uint32_t ui; - } ci; - ci.fv = f; - - uint32_t x = ci.ui; - uint32_t sign = (unsigned short)(x >> 31); - uint32_t mantissa; - uint32_t exponent; - uint16_t hf; - - // get mantissa - mantissa = x & ((1 << 23) - 1); - // get exponent bits - exponent = x & (0xFF << 23); - if (exponent >= 0x47800000) { - // check if the original single precision float number is a NaN - if (mantissa && (exponent == (0xFF << 23))) { - // we have a single precision NaN - mantissa = (1 << 23) - 1; - } else { - // 16-bit half-float representation stores number as Inf - mantissa = 0; - } - hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) | - (uint16_t)(mantissa >> 13); - } - // check if exponent is <= -15 - else if (exponent <= 0x38000000) { - /* - // store a denorm half-float value or zero - exponent = (0x38000000 - exponent) >> 23; - mantissa >>= (14 + exponent); - - hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); - */ - hf = 0; //denormals do not work for 3D, convert to zero + return abs(p_left - p_right) < tolerance; +} + +_ALWAYS_INLINE_ bool is_zero_approx(double p_value) { + return abs(p_value) < CMP_EPSILON; +} +_ALWAYS_INLINE_ bool is_zero_approx(float p_value) { + return abs(p_value) < (float)CMP_EPSILON; +} + +_ALWAYS_INLINE_ bool is_same(double p_left, double p_right) { + return (p_left == p_right) || (is_nan(p_left) && is_nan(p_right)); +} +_ALWAYS_INLINE_ bool is_same(float p_left, float p_right) { + return (p_left == p_right) || (is_nan(p_left) && is_nan(p_right)); +} + +_ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { + if (is_equal_approx(p_from, p_to)) { + if (likely(p_from <= p_to)) { + return p_s <= p_from ? 0.0 : 1.0; } else { - hf = (((uint16_t)sign) << 15) | - (uint16_t)((exponent - 0x38000000) >> 13) | - (uint16_t)(mantissa >> 13); + return p_s <= p_to ? 1.0 : 0.0; } - - return hf; } - - static _ALWAYS_INLINE_ float snap_scalar(float p_offset, float p_step, float p_target) { - return p_step != 0 ? Math::snapped(p_target - p_offset, p_step) + p_offset : p_target; + double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); + return s * s * (3.0 - 2.0 * s); +} +_ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { + if (is_equal_approx(p_from, p_to)) { + if (likely(p_from <= p_to)) { + return p_s <= p_from ? 0.0f : 1.0f; + } else { + return p_s <= p_to ? 1.0f : 0.0f; + } } + float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); + return s * s * (3.0f - 2.0f * s); +} - static _ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) { - if (p_step != 0) { - float a = Math::snapped(p_target - p_offset, p_step + p_separation) + p_offset; - float b = a; - if (p_target >= 0) { - b -= p_separation; - } else { - b += p_step; +_ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { + return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; +} +_ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { + return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; +} + +_ALWAYS_INLINE_ double rotate_toward(double p_from, double p_to, double p_delta) { + double difference = angle_difference(p_from, p_to); + double abs_difference = abs(difference); + // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). + return p_from + CLAMP(p_delta, abs_difference - PI, abs_difference) * (difference >= 0.0 ? 1.0 : -1.0); +} +_ALWAYS_INLINE_ float rotate_toward(float p_from, float p_to, float p_delta) { + float difference = angle_difference(p_from, p_to); + float abs_difference = abs(difference); + // When `p_delta < 0` move no further than to PI radians away from `p_to` (as PI is the max possible angle distance). + return p_from + CLAMP(p_delta, abs_difference - (float)PI, abs_difference) * (difference >= 0.0f ? 1.0f : -1.0f); +} + +_ALWAYS_INLINE_ double linear_to_db(double p_linear) { + return log(p_linear) * 8.6858896380650365530225783783321; +} +_ALWAYS_INLINE_ float linear_to_db(float p_linear) { + return log(p_linear) * (float)8.6858896380650365530225783783321; +} + +_ALWAYS_INLINE_ double db_to_linear(double p_db) { + return exp(p_db * 0.11512925464970228420089957273422); +} +_ALWAYS_INLINE_ float db_to_linear(float p_db) { + return exp(p_db * (float)0.11512925464970228420089957273422); +} + +_ALWAYS_INLINE_ double round(double p_val) { + return ::round(p_val); +} +_ALWAYS_INLINE_ float round(float p_val) { + return ::roundf(p_val); +} + +_ALWAYS_INLINE_ double wrapf(double p_value, double p_min, double p_max) { + double range = p_max - p_min; + if (is_zero_approx(range)) { + return p_min; + } + double result = p_value - (range * floor((p_value - p_min) / range)); + if (is_equal_approx(result, p_max)) { + return p_min; + } + return result; +} +_ALWAYS_INLINE_ float wrapf(float p_value, float p_min, float p_max) { + float range = p_max - p_min; + if (is_zero_approx(range)) { + return p_min; + } + float result = p_value - (range * floor((p_value - p_min) / range)); + if (is_equal_approx(result, p_max)) { + return p_min; + } + return result; +} + +_ALWAYS_INLINE_ int64_t wrapi(int64_t p_value, int64_t p_min, int64_t p_max) { + int64_t range = p_max - p_min; + return range == 0 ? p_min : p_min + ((((p_value - p_min) % range) + range) % range); +} + +_ALWAYS_INLINE_ double fract(double p_value) { + return p_value - floor(p_value); +} +_ALWAYS_INLINE_ float fract(float p_value) { + return p_value - floor(p_value); +} + +_ALWAYS_INLINE_ double pingpong(double p_value, double p_length) { + return (p_length != 0.0) ? abs(fract((p_value - p_length) / (p_length * 2.0)) * p_length * 2.0 - p_length) : 0.0; +} +_ALWAYS_INLINE_ float pingpong(float p_value, float p_length) { + return (p_length != 0.0f) ? abs(fract((p_value - p_length) / (p_length * 2.0f)) * p_length * 2.0f - p_length) : 0.0f; +} + +// double only, as these functions are mainly used by the editor and not performance-critical, +double ease(double p_x, double p_c); +int step_decimals(double p_step); +int range_step_decimals(double p_step); // For editor use only. +double snapped(double p_value, double p_step); + +uint32_t larger_prime(uint32_t p_val); + +void seed(uint64_t p_seed); +void randomize(); +uint32_t rand_from_seed(uint64_t *p_seed); +uint32_t rand(); +_ALWAYS_INLINE_ double randd() { + return (double)rand() / (double)UINT32_MAX; +} +_ALWAYS_INLINE_ float randf() { + return (float)rand() / (float)UINT32_MAX; +} +double randfn(double p_mean, double p_deviation); + +double random(double p_from, double p_to); +float random(float p_from, float p_to); +int random(int p_from, int p_to); + +// This function should be as fast as possible and rounding mode should not matter. +_ALWAYS_INLINE_ int fast_ftoi(float p_value) { + // Assuming every supported compiler has `lrint()`. + return lrintf(p_value); +} + +_ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t p_half) { + uint16_t h_exp, h_sig; + uint32_t f_sgn, f_exp, f_sig; + + h_exp = (p_half & 0x7c00u); + f_sgn = ((uint32_t)p_half & 0x8000u) << 16; + switch (h_exp) { + case 0x0000u: /* 0 or subnormal */ + h_sig = (p_half & 0x03ffu); + /* Signed zero */ + if (h_sig == 0) { + return f_sgn; } - return (Math::abs(p_target - a) < Math::abs(p_target - b)) ? a : b; - } - return p_target; + /* Subnormal */ + h_sig <<= 1; + while ((h_sig & 0x0400u) == 0) { + h_sig <<= 1; + h_exp++; + } + f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23; + f_sig = ((uint32_t)(h_sig & 0x03ffu)) << 13; + return f_sgn + f_exp + f_sig; + case 0x7c00u: /* inf or NaN */ + /* All-ones exponent and a copy of the significand */ + return f_sgn + 0x7f800000u + (((uint32_t)(p_half & 0x03ffu)) << 13); + default: /* normalized */ + /* Just need to adjust the exponent and shift */ + return f_sgn + (((uint32_t)(p_half & 0x7fffu) + 0x1c000u) << 13); } -}; +} -#endif // MATH_FUNCS_H +_ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *p_half) { + union { + uint32_t u32; + float f32; + } u; + + u.u32 = halfbits_to_floatbits(*p_half); + return u.f32; +} + +_ALWAYS_INLINE_ float half_to_float(const uint16_t p_half) { + return halfptr_to_float(&p_half); +} + +_ALWAYS_INLINE_ uint16_t make_half_float(float p_value) { + union { + float fv; + uint32_t ui; + } ci; + ci.fv = p_value; + + uint32_t x = ci.ui; + uint32_t sign = (unsigned short)(x >> 31); + uint32_t mantissa; + uint32_t exponent; + uint16_t hf; + + // get mantissa + mantissa = x & ((1 << 23) - 1); + // get exponent bits + exponent = x & (0xFF << 23); + if (exponent >= 0x47800000) { + // check if the original single precision float number is a NaN + if (mantissa && (exponent == (0xFF << 23))) { + // we have a single precision NaN + mantissa = (1 << 23) - 1; + } else { + // 16-bit half-float representation stores number as Inf + mantissa = 0; + } + hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) | + (uint16_t)(mantissa >> 13); + } + // check if exponent is <= -15 + else if (exponent <= 0x38000000) { + /* + // store a denorm half-float value or zero + exponent = (0x38000000 - exponent) >> 23; + mantissa >>= (14 + exponent); + + hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); + */ + hf = 0; //denormals do not work for 3D, convert to zero + } else { + hf = (((uint16_t)sign) << 15) | + (uint16_t)((exponent - 0x38000000) >> 13) | + (uint16_t)(mantissa >> 13); + } + + return hf; +} + +_ALWAYS_INLINE_ float snap_scalar(float p_offset, float p_step, float p_target) { + return p_step != 0 ? snapped(p_target - p_offset, p_step) + p_offset : p_target; +} + +_ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) { + if (p_step != 0) { + float a = snapped(p_target - p_offset, p_step + p_separation) + p_offset; + float b = a; + if (p_target >= 0) { + b -= p_separation; + } else { + b += p_step; + } + return (abs(p_target - a) < abs(p_target - b)) ? a : b; + } + return p_target; +} + +}; // namespace Math diff --git a/engine/core/math/plane.cpp b/engine/core/math/plane.cpp index 6b9bcea0..74783b2a 100644 --- a/engine/core/math/plane.cpp +++ b/engine/core/math/plane.cpp @@ -58,7 +58,7 @@ Vector3 Plane::get_any_perpendicular_normal() const { static const Vector3 p2 = Vector3(0, 1, 0); Vector3 p; - if (ABS(normal.dot(p1)) > 0.99f) { // if too similar to p1 + if (Math::abs(normal.dot(p1)) > 0.99f) { // if too similar to p1 p = p2; // use p2 } else { p = p1; // use p1 @@ -172,6 +172,10 @@ bool Plane::is_equal_approx(const Plane &p_plane) const { return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d); } +bool Plane::is_same(const Plane &p_plane) const { + return normal.is_same(p_plane.normal) && Math::is_same(d, p_plane.d); +} + bool Plane::is_finite() const { return normal.is_finite() && Math::is_finite(d); } diff --git a/engine/core/math/plane.h b/engine/core/math/plane.h index 65783ff4..77a53e57 100644 --- a/engine/core/math/plane.h +++ b/engine/core/math/plane.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PLANE_H -#define PLANE_H +#pragma once #include "core/math/vector3.h" @@ -71,21 +70,22 @@ struct [[nodiscard]] Plane { /* misc */ - Plane operator-() const { return Plane(-normal, -d); } + constexpr Plane operator-() const { return Plane(-normal, -d); } bool is_equal_approx(const Plane &p_plane) const; + bool is_same(const Plane &p_plane) const; bool is_equal_approx_any_side(const Plane &p_plane) const; bool is_finite() const; - _FORCE_INLINE_ bool operator==(const Plane &p_plane) const; - _FORCE_INLINE_ bool operator!=(const Plane &p_plane) const; + constexpr bool operator==(const Plane &p_plane) const; + constexpr bool operator!=(const Plane &p_plane) const; operator String() const; - _FORCE_INLINE_ Plane() {} - _FORCE_INLINE_ Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) : + Plane() = default; + constexpr Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) : normal(p_a, p_b, p_c), d(p_d) {} - _FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d = 0.0); + constexpr Plane(const Vector3 &p_normal, real_t p_d = 0.0); _FORCE_INLINE_ Plane(const Vector3 &p_normal, const Vector3 &p_point); _FORCE_INLINE_ Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir = CLOCKWISE); }; @@ -100,11 +100,11 @@ real_t Plane::distance_to(const Vector3 &p_point) const { bool Plane::has_point(const Vector3 &p_point, real_t p_tolerance) const { real_t dist = normal.dot(p_point) - d; - dist = ABS(dist); + dist = Math::abs(dist); return (dist <= p_tolerance); } -Plane::Plane(const Vector3 &p_normal, real_t p_d) : +constexpr Plane::Plane(const Vector3 &p_normal, real_t p_d) : normal(p_normal), d(p_d) { } @@ -125,12 +125,13 @@ Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_ d = normal.dot(p_point1); } -bool Plane::operator==(const Plane &p_plane) const { +constexpr bool Plane::operator==(const Plane &p_plane) const { return normal == p_plane.normal && d == p_plane.d; } -bool Plane::operator!=(const Plane &p_plane) const { +constexpr bool Plane::operator!=(const Plane &p_plane) const { return normal != p_plane.normal || d != p_plane.d; } -#endif // PLANE_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/projection.cpp b/engine/core/math/projection.cpp index 20638826..a71e44d9 100644 --- a/engine/core/math/projection.cpp +++ b/engine/core/math/projection.cpp @@ -402,82 +402,35 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r } real_t Projection::get_z_far() const { - const real_t *matrix = (const real_t *)columns; - Plane new_plane = Plane(matrix[3] - matrix[2], - matrix[7] - matrix[6], - matrix[11] - matrix[10], - matrix[15] - matrix[14]); - - new_plane.normalize(); - - return new_plane.d; + // NOTE: This assumes z-facing near and far planes, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0) + return (columns[3][3] - columns[3][2]) / (columns[2][3] - columns[2][2]); } real_t Projection::get_z_near() const { - const real_t *matrix = (const real_t *)columns; - Plane new_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - - new_plane.normalize(); - return new_plane.d; + // NOTE: This assumes z-facing near and far planes, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0) + return (columns[3][3] + columns[3][2]) / (columns[2][3] + columns[2][2]); } Vector2 Projection::get_viewport_half_extents() const { - const real_t *matrix = (const real_t *)columns; - ///////--- Near Plane ---/////// - Plane near_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - near_plane.normalize(); - - ///////--- Right Plane ---/////// - Plane right_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - Plane top_plane = Plane(matrix[3] - matrix[1], - matrix[7] - matrix[5], - matrix[11] - matrix[9], - -matrix[15] + matrix[13]); - top_plane.normalize(); - - Vector3 res; - near_plane.intersect_3(right_plane, top_plane, &res); - - return Vector2(res.x, res.y); + // NOTE: This assumes a symmetrical frustum, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0) + real_t w = -get_z_near() * columns[2][3] + columns[3][3]; + return Vector2(w / columns[0][0], w / columns[1][1]); } Vector2 Projection::get_far_plane_half_extents() const { - const real_t *matrix = (const real_t *)columns; - ///////--- Far Plane ---/////// - Plane far_plane = Plane(matrix[3] - matrix[2], - matrix[7] - matrix[6], - matrix[11] - matrix[10], - -matrix[15] + matrix[14]); - far_plane.normalize(); - - ///////--- Right Plane ---/////// - Plane right_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - Plane top_plane = Plane(matrix[3] - matrix[1], - matrix[7] - matrix[5], - matrix[11] - matrix[9], - -matrix[15] + matrix[13]); - top_plane.normalize(); - - Vector3 res; - far_plane.intersect_3(right_plane, top_plane, &res); - - return Vector2(res.x, res.y); + // NOTE: This assumes a symmetrical frustum, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0) + real_t w = -get_z_far() * columns[2][3] + columns[3][3]; + return Vector2(w / columns[0][0], w / columns[1][1]); } bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { @@ -827,24 +780,8 @@ void Projection::flip_y() { } } -Projection::Projection() { - set_identity(); -} - -Projection Projection::operator*(const Projection &p_matrix) const { - Projection new_matrix; - - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { - real_t ab = 0; - for (int k = 0; k < 4; k++) { - ab += columns[k][i] * p_matrix.columns[j][k]; - } - new_matrix.columns[j][i] = ab; - } - } - - return new_matrix; +bool Projection::is_same(const Projection &p_cam) const { + return columns[0].is_same(p_cam.columns[0]) && columns[1].is_same(p_cam.columns[1]) && columns[2].is_same(p_cam.columns[2]) && columns[3].is_same(p_cam.columns[3]); } void Projection::set_depth_correction(bool p_flip_y, bool p_reverse_z, bool p_remap_z) { @@ -919,53 +856,45 @@ Projection::operator String() const { } real_t Projection::get_aspect() const { - Vector2 vp_he = get_viewport_half_extents(); - return vp_he.x / vp_he.y; + // NOTE: This assumes a rectangular projection plane, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + return columns[1][1] / columns[0][0]; } int Projection::get_pixels_per_meter(int p_for_pixel_width) const { - Vector3 result = xform(Vector3(1, 0, -1)); - - return int((result.x * 0.5 + 0.5) * p_for_pixel_width); + // NOTE: This assumes a rectangular projection plane, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + real_t width = 2 * (-get_z_near() * columns[2][3] + columns[3][3]) / columns[0][0]; + return p_for_pixel_width / width; // Note : return type should be real_t (kept as int for compatibility for now). } bool Projection::is_orthogonal() const { - return columns[3][3] == 1.0; + // NOTE: This assumes that the matrix is a projection across z-axis + // i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0 + return columns[2][3] == 0.0; } real_t Projection::get_fov() const { - const real_t *matrix = (const real_t *)columns; - - Plane right_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - if ((matrix[8] == 0) && (matrix[9] == 0)) { - return Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x))) * 2.0; + // NOTE: This assumes a rectangular projection plane, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + if (columns[2][0] == 0) { + return Math::rad_to_deg(2 * Math::atan2(1, columns[0][0])); } else { - // our frustum is asymmetrical need to calculate the left planes angle separately.. - Plane left_plane = Plane(matrix[3] + matrix[0], - matrix[7] + matrix[4], - matrix[11] + matrix[8], - matrix[15] + matrix[12]); - left_plane.normalize(); - - return Math::rad_to_deg(Math::acos(Math::abs(left_plane.normal.x))) + Math::rad_to_deg(Math::acos(Math::abs(right_plane.normal.x))); + // The frustum is asymmetrical so we need to calculate the left and right angles separately. + real_t right = Math::atan2(columns[2][0] + 1, columns[0][0]); + real_t left = Math::atan2(columns[2][0] - 1, columns[0][0]); + return Math::rad_to_deg(right - left); } } real_t Projection::get_lod_multiplier() const { - if (is_orthogonal()) { - return get_viewport_half_extents().x; - } else { - const real_t zn = get_z_near(); - const real_t width = get_viewport_half_extents().x * 2.0f; - return 1.0f / (zn / width); - } - - // Usage is lod_size / (lod_distance * multiplier) < threshold + // NOTE: This assumes a rectangular projection plane, i.e. that : + // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0) + // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0) + return 2 / columns[0][0]; } void Projection::make_scale(const Vector3 &p_scale) { @@ -1028,13 +957,6 @@ Projection::operator Transform3D() const { return tr; } -Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) { - columns[0] = p_x; - columns[1] = p_y; - columns[2] = p_z; - columns[3] = p_w; -} - Projection::Projection(const Transform3D &p_transform) { const Transform3D &tr = p_transform; real_t *m = &columns[0][0]; @@ -1056,6 +978,3 @@ Projection::Projection(const Transform3D &p_transform) { m[14] = tr.origin.z; m[15] = 1.0; } - -Projection::~Projection() { -} diff --git a/engine/core/math/projection.h b/engine/core/math/projection.h index 5af43561..6d5f585c 100644 --- a/engine/core/math/projection.h +++ b/engine/core/math/projection.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef PROJECTION_H -#define PROJECTION_H +#pragma once #include "core/math/vector3.h" #include "core/math/vector4.h" @@ -53,14 +52,19 @@ struct [[nodiscard]] Projection { PLANE_BOTTOM }; - Vector4 columns[4]; + Vector4 columns[4] = { + { 1, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, + }; - _FORCE_INLINE_ const Vector4 &operator[](int p_axis) const { + constexpr const Vector4 &operator[](int p_axis) const { DEV_ASSERT((unsigned int)p_axis < 4); return columns[p_axis]; } - _FORCE_INLINE_ Vector4 &operator[](int p_axis) { + constexpr Vector4 &operator[](int p_axis) { DEV_ASSERT((unsigned int)p_axis < 4); return columns[p_axis]; } @@ -115,7 +119,7 @@ struct [[nodiscard]] Projection { void invert(); Projection inverse() const; - Projection operator*(const Projection &p_matrix) const; + constexpr Projection operator*(const Projection &p_matrix) const; Plane xform4(const Plane &p_vec4) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const; @@ -133,7 +137,9 @@ struct [[nodiscard]] Projection { void flip_y(); - bool operator==(const Projection &p_cam) const { + bool is_same(const Projection &p_cam) const; + + constexpr bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { if (columns[i][j] != p_cam.columns[i][j]) { @@ -144,18 +150,41 @@ struct [[nodiscard]] Projection { return true; } - bool operator!=(const Projection &p_cam) const { + constexpr bool operator!=(const Projection &p_cam) const { return !(*this == p_cam); } real_t get_lod_multiplier() const; - Projection(); - Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w); + Projection() = default; + constexpr Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) : + columns{ p_x, p_y, p_z, p_w } {} + constexpr Projection(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_xw, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_yw, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_zw, real_t p_wx, real_t p_wy, real_t p_wz, real_t p_ww) : + columns{ + { p_xx, p_xy, p_xz, p_xw }, + { p_yx, p_yy, p_yz, p_yw }, + { p_zx, p_zy, p_zz, p_zw }, + { p_wx, p_wy, p_wz, p_ww }, + } {} Projection(const Transform3D &p_transform); - ~Projection(); }; +constexpr Projection Projection::operator*(const Projection &p_matrix) const { + Projection new_matrix; + + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + real_t ab = 0; + for (int k = 0; k < 4; k++) { + ab += columns[k][i] * p_matrix.columns[j][k]; + } + new_matrix.columns[j][i] = ab; + } + } + + return new_matrix; +} + Vector3 Projection::xform(const Vector3 &p_vec3) const { Vector3 ret; ret.x = columns[0][0] * p_vec3.x + columns[1][0] * p_vec3.y + columns[2][0] * p_vec3.z + columns[3][0]; @@ -164,5 +193,3 @@ Vector3 Projection::xform(const Vector3 &p_vec3) const { real_t w = columns[0][3] * p_vec3.x + columns[1][3] * p_vec3.y + columns[2][3] * p_vec3.z + columns[3][3]; return ret / w; } - -#endif // PROJECTION_H diff --git a/engine/core/math/quaternion.cpp b/engine/core/math/quaternion.cpp index 08eac14b..6c0b491a 100644 --- a/engine/core/math/quaternion.cpp +++ b/engine/core/math/quaternion.cpp @@ -46,26 +46,14 @@ Vector3 Quaternion::get_euler(EulerOrder p_order) const { return Basis(*this).get_euler(p_order); } -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; - w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z; - x = xx; - y = yy; - z = zz; -} - -Quaternion Quaternion::operator*(const Quaternion &p_q) const { - Quaternion r = *this; - r *= p_q; - return r; -} - 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); } +bool Quaternion::is_same(const Quaternion &p_quaternion) const { + return Math::is_same(x, p_quaternion.x) && Math::is_same(y, p_quaternion.y) && Math::is_same(z, p_quaternion.z) && Math::is_same(w, p_quaternion.w); +} + bool Quaternion::is_finite() const { return Math::is_finite(x) && Math::is_finite(y) && Math::is_finite(z) && Math::is_finite(w); } diff --git a/engine/core/math/quaternion.h b/engine/core/math/quaternion.h index 58a4ec5b..6dae7a79 100644 --- a/engine/core/math/quaternion.h +++ b/engine/core/math/quaternion.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef QUATERNION_H -#define QUATERNION_H +#pragma once #include "core/math/math_funcs.h" #include "core/math/vector3.h" @@ -37,6 +36,7 @@ struct [[nodiscard]] Quaternion { union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -44,6 +44,7 @@ struct [[nodiscard]] Quaternion { real_t w; }; real_t components[4] = { 0, 0, 0, 1.0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_idx) { @@ -54,6 +55,7 @@ struct [[nodiscard]] Quaternion { } _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Quaternion &p_quaternion) const; + bool is_same(const Quaternion &p_quaternion) const; bool is_finite() const; real_t length() const; void normalize(); @@ -84,8 +86,8 @@ struct [[nodiscard]] Quaternion { r_axis.z = z * r; } - void operator*=(const Quaternion &p_q); - Quaternion operator*(const Quaternion &p_q) const; + constexpr void operator*=(const Quaternion &p_q); + constexpr Quaternion operator*(const Quaternion &p_q) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_v) const { #ifdef MATH_CHECKS @@ -100,40 +102,33 @@ struct [[nodiscard]] Quaternion { return inverse().xform(p_v); } - _FORCE_INLINE_ void operator+=(const Quaternion &p_q); - _FORCE_INLINE_ void operator-=(const Quaternion &p_q); - _FORCE_INLINE_ void operator*=(real_t p_s); - _FORCE_INLINE_ void operator/=(real_t p_s); - _FORCE_INLINE_ Quaternion operator+(const Quaternion &p_q2) const; - _FORCE_INLINE_ Quaternion operator-(const Quaternion &p_q2) const; - _FORCE_INLINE_ Quaternion operator-() const; - _FORCE_INLINE_ Quaternion operator*(real_t p_s) const; - _FORCE_INLINE_ Quaternion operator/(real_t p_s) const; + constexpr void operator+=(const Quaternion &p_q); + constexpr void operator-=(const Quaternion &p_q); + constexpr void operator*=(real_t p_s); + constexpr void operator/=(real_t p_s); + constexpr Quaternion operator+(const Quaternion &p_q2) const; + constexpr Quaternion operator-(const Quaternion &p_q2) const; + constexpr Quaternion operator-() const; + constexpr Quaternion operator*(real_t p_s) const; + constexpr Quaternion operator/(real_t p_s) const; - _FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const; - _FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const; + constexpr bool operator==(const Quaternion &p_quaternion) const; + constexpr bool operator!=(const Quaternion &p_quaternion) const; operator String() const; - _FORCE_INLINE_ Quaternion() {} + constexpr Quaternion() : + x(0), y(0), z(0), w(1) {} - _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) { - } + constexpr 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) {} Quaternion(const Vector3 &p_axis, real_t p_angle); - Quaternion(const Quaternion &p_q) : - x(p_q.x), - y(p_q.y), - z(p_q.z), - w(p_q.w) { - } + constexpr Quaternion(const Quaternion &p_q) : + x(p_q.x), y(p_q.y), z(p_q.z), w(p_q.w) {} - void operator=(const Quaternion &p_q) { + constexpr void operator=(const Quaternion &p_q) { x = p_q.x; y = p_q.y; z = p_q.z; @@ -178,64 +173,78 @@ real_t Quaternion::length_squared() const { return dot(*this); } -void Quaternion::operator+=(const Quaternion &p_q) { +constexpr void Quaternion::operator+=(const Quaternion &p_q) { x += p_q.x; y += p_q.y; z += p_q.z; w += p_q.w; } -void Quaternion::operator-=(const Quaternion &p_q) { +constexpr void Quaternion::operator-=(const Quaternion &p_q) { x -= p_q.x; y -= p_q.y; z -= p_q.z; w -= p_q.w; } -void Quaternion::operator*=(real_t p_s) { +constexpr void Quaternion::operator*=(real_t p_s) { x *= p_s; y *= p_s; z *= p_s; w *= p_s; } -void Quaternion::operator/=(real_t p_s) { - *this *= 1.0f / p_s; +constexpr void Quaternion::operator/=(real_t p_s) { + *this *= (1 / p_s); } -Quaternion Quaternion::operator+(const Quaternion &p_q2) const { +constexpr Quaternion Quaternion::operator+(const Quaternion &p_q2) const { const Quaternion &q1 = *this; return Quaternion(q1.x + p_q2.x, q1.y + p_q2.y, q1.z + p_q2.z, q1.w + p_q2.w); } -Quaternion Quaternion::operator-(const Quaternion &p_q2) const { +constexpr Quaternion Quaternion::operator-(const Quaternion &p_q2) const { const Quaternion &q1 = *this; return Quaternion(q1.x - p_q2.x, q1.y - p_q2.y, q1.z - p_q2.z, q1.w - p_q2.w); } -Quaternion Quaternion::operator-() const { +constexpr Quaternion Quaternion::operator-() const { const Quaternion &q2 = *this; return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w); } -Quaternion Quaternion::operator*(real_t p_s) const { +constexpr Quaternion Quaternion::operator*(real_t p_s) const { return Quaternion(x * p_s, y * p_s, z * p_s, w * p_s); } -Quaternion Quaternion::operator/(real_t p_s) const { - return *this * (1.0f / p_s); +constexpr Quaternion Quaternion::operator/(real_t p_s) const { + return *this * (1 / p_s); } -bool Quaternion::operator==(const Quaternion &p_quaternion) const { +constexpr 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 Quaternion::operator!=(const Quaternion &p_quaternion) const { +constexpr 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_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) { - return p_quaternion * p_real; +constexpr 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; + w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z; + x = xx; + y = yy; + z = zz; } -#endif // QUATERNION_H +constexpr Quaternion Quaternion::operator*(const Quaternion &p_q) const { + Quaternion r = *this; + r *= p_q; + return r; +} + +constexpr Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) { + return p_quaternion * p_real; +} diff --git a/engine/core/math/quick_hull.cpp b/engine/core/math/quick_hull.cpp index 34a0c021..360b272e 100644 --- a/engine/core/math/quick_hull.cpp +++ b/engine/core/math/quick_hull.cpp @@ -30,6 +30,9 @@ #include "quick_hull.h" +#include "core/templates/hash_map.h" +#include "core/templates/hash_set.h" + uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF; Error QuickHull::build(const Vector &p_points, Geometry3D::MeshData &r_mesh) { @@ -320,7 +323,7 @@ Error QuickHull::build(const Vector &p_points, Geometry3D::MeshData &r_ for (List::Element *&E : new_faces) { Face &f2 = E->get(); - if (f2.points_over.size() == 0) { + if (f2.points_over.is_empty()) { faces.move_to_front(E); } } diff --git a/engine/core/math/quick_hull.h b/engine/core/math/quick_hull.h index f4891a7c..e374211d 100644 --- a/engine/core/math/quick_hull.h +++ b/engine/core/math/quick_hull.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef QUICK_HULL_H -#define QUICK_HULL_H +#pragma once #include "core/math/geometry_3d.h" #include "core/templates/list.h" @@ -89,5 +88,3 @@ public: static uint32_t debug_stop_after; static Error build(const Vector &p_points, Geometry3D::MeshData &r_mesh); }; - -#endif // QUICK_HULL_H diff --git a/engine/core/math/random_number_generator.h b/engine/core/math/random_number_generator.h index 7ec4cdff..aa21b41a 100644 --- a/engine/core/math/random_number_generator.h +++ b/engine/core/math/random_number_generator.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RANDOM_NUMBER_GENERATOR_H -#define RANDOM_NUMBER_GENERATOR_H +#pragma once #include "core/math/random_pcg.h" #include "core/object/ref_counted.h" @@ -61,5 +60,3 @@ public: RandomNumberGenerator() { randbase.randomize(); } }; - -#endif // RANDOM_NUMBER_GENERATOR_H diff --git a/engine/core/math/random_pcg.h b/engine/core/math/random_pcg.h index 6bad7005..f39cd7ab 100644 --- a/engine/core/math/random_pcg.h +++ b/engine/core/math/random_pcg.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RANDOM_PCG_H -#define RANDOM_PCG_H +#pragma once #include "core/math/math_defs.h" @@ -135,19 +134,17 @@ public: if (temp < CMP_EPSILON) { temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function. } - return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. + return p_mean + p_deviation * (cos(Math::TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. } _FORCE_INLINE_ float randfn(float p_mean, float p_deviation) { float temp = randf(); if (temp < CMP_EPSILON) { temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function. } - return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. + return p_mean + p_deviation * (cos((float)Math::TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform. } double random(double p_from, double p_to); float random(float p_from, float p_to); int random(int p_from, int p_to); }; - -#endif // RANDOM_PCG_H diff --git a/engine/core/math/rect2.cpp b/engine/core/math/rect2.cpp index 7f77b078..102a9e4b 100644 --- a/engine/core/math/rect2.cpp +++ b/engine/core/math/rect2.cpp @@ -38,6 +38,10 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const { return position.is_equal_approx(p_rect.position) && size.is_equal_approx(p_rect.size); } +bool Rect2::is_same(const Rect2 &p_rect) const { + return position.is_same(p_rect.position) && size.is_same(p_rect.size); +} + bool Rect2::is_finite() const { return position.is_finite() && size.is_finite(); } diff --git a/engine/core/math/rect2.h b/engine/core/math/rect2.h index 817923c1..27a701e9 100644 --- a/engine/core/math/rect2.h +++ b/engine/core/math/rect2.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RECT2_H -#define RECT2_H +#pragma once #include "core/error/error_macros.h" #include "core/math/vector2.h" @@ -203,10 +202,11 @@ struct [[nodiscard]] Rect2 { } bool is_equal_approx(const Rect2 &p_rect) const; + bool is_same(const Rect2 &p_rect) const; bool is_finite() const; - bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } + constexpr bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } + constexpr bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } inline Rect2 grow(real_t p_amount) const { Rect2 g = *this; @@ -361,15 +361,16 @@ struct [[nodiscard]] Rect2 { operator String() const; operator Rect2i() const; - Rect2() {} - Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : + Rect2() = default; + constexpr Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) : position(Point2(p_x, p_y)), size(Size2(p_width, p_height)) { } - Rect2(const Point2 &p_pos, const Size2 &p_size) : + constexpr Rect2(const Point2 &p_pos, const Size2 &p_size) : position(p_pos), size(p_size) { } }; -#endif // RECT2_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/rect2i.h b/engine/core/math/rect2i.h index 5f3a3d54..d0b8b5e7 100644 --- a/engine/core/math/rect2i.h +++ b/engine/core/math/rect2i.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RECT2I_H -#define RECT2I_H +#pragma once #include "core/error/error_macros.h" #include "core/math/vector2i.h" @@ -144,8 +143,8 @@ struct [[nodiscard]] Rect2i { return true; } - bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } + constexpr bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } + constexpr bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } Rect2i grow(int p_amount) const { Rect2i g = *this; @@ -227,15 +226,16 @@ struct [[nodiscard]] Rect2i { operator String() const; operator Rect2() const; - Rect2i() {} - Rect2i(int p_x, int p_y, int p_width, int p_height) : + Rect2i() = default; + constexpr Rect2i(int p_x, int p_y, int p_width, int p_height) : position(Point2i(p_x, p_y)), size(Size2i(p_width, p_height)) { } - Rect2i(const Point2i &p_pos, const Size2i &p_size) : + constexpr Rect2i(const Point2i &p_pos, const Size2i &p_size) : position(p_pos), size(p_size) { } }; -#endif // RECT2I_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/static_raycaster.h b/engine/core/math/static_raycaster.h index 74e4b751..fbb5194c 100644 --- a/engine/core/math/static_raycaster.h +++ b/engine/core/math/static_raycaster.h @@ -28,21 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef STATIC_RAYCASTER_H -#define STATIC_RAYCASTER_H +#pragma once #include "core/object/ref_counted.h" -#if !defined(__aligned) - -#if defined(_WIN32) && defined(_MSC_VER) -#define __aligned(...) __declspec(align(__VA_ARGS__)) -#else -#define __aligned(...) __attribute__((aligned(__VA_ARGS__))) -#endif - -#endif - class StaticRaycaster : public RefCounted { GDCLASS(StaticRaycaster, RefCounted) protected: @@ -50,7 +39,7 @@ protected: public: // Compatible with embree4 rays. - struct __aligned(16) Ray { + struct alignas(16) Ray { const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h /*! Default construction does nothing. */ @@ -62,7 +51,7 @@ public: _FORCE_INLINE_ Ray(const Vector3 &p_org, const Vector3 &p_dir, float p_tnear = 0.0f, - float p_tfar = INFINITY) : + float p_tfar = Math::INF) : org(p_org), tnear(p_tnear), dir(p_dir), @@ -107,5 +96,3 @@ public: static Ref create(); }; - -#endif // STATIC_RAYCASTER_H diff --git a/engine/core/math/transform_2d.cpp b/engine/core/math/transform_2d.cpp index f6525fe5..b5a971e7 100644 --- a/engine/core/math/transform_2d.cpp +++ b/engine/core/math/transform_2d.cpp @@ -71,12 +71,12 @@ void Transform2D::rotate(real_t p_angle) { real_t Transform2D::get_skew() const { real_t det = determinant(); - return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math_PI * 0.5f; + return Math::acos(columns[0].normalized().dot(SIGN(det) * columns[1].normalized())) - (real_t)Math::PI * 0.5f; } void Transform2D::set_skew(real_t p_angle) { real_t det = determinant(); - columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math_PI * 0.5f + p_angle)).normalized() * columns[1].length(); + columns[1] = SIGN(det) * columns[0].rotated(((real_t)Math::PI * 0.5f + p_angle)).normalized() * columns[1].length(); } real_t Transform2D::get_rotation() const { @@ -180,6 +180,10 @@ bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { return columns[0].is_equal_approx(p_transform.columns[0]) && columns[1].is_equal_approx(p_transform.columns[1]) && columns[2].is_equal_approx(p_transform.columns[2]); } +bool Transform2D::is_same(const Transform2D &p_transform) const { + return columns[0].is_same(p_transform.columns[0]) && columns[1].is_same(p_transform.columns[1]) && columns[2].is_same(p_transform.columns[2]); +} + bool Transform2D::is_finite() const { return columns[0].is_finite() && columns[1].is_finite() && columns[2].is_finite(); } @@ -191,26 +195,6 @@ Transform2D Transform2D::looking_at(const Vector2 &p_target) const { return return_trans; } -bool Transform2D::operator==(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (columns[i] != p_transform.columns[i]) { - return false; - } - } - - return true; -} - -bool Transform2D::operator!=(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (columns[i] != p_transform.columns[i]) { - return true; - } - } - - return false; -} - void Transform2D::operator*=(const Transform2D &p_transform) { columns[2] = xform(p_transform.columns[2]); @@ -283,30 +267,6 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t get_origin().lerp(p_transform.get_origin(), p_weight)); } -void Transform2D::operator*=(real_t p_val) { - columns[0] *= p_val; - columns[1] *= p_val; - columns[2] *= p_val; -} - -Transform2D Transform2D::operator*(real_t p_val) const { - Transform2D ret(*this); - ret *= p_val; - return ret; -} - -void Transform2D::operator/=(real_t p_val) { - columns[0] /= p_val; - columns[1] /= p_val; - columns[2] /= p_val; -} - -Transform2D Transform2D::operator/(real_t p_val) const { - Transform2D ret(*this); - ret /= p_val; - return ret; -} - Transform2D::operator String() const { return "[X: " + columns[0].operator String() + ", Y: " + columns[1].operator String() + diff --git a/engine/core/math/transform_2d.h b/engine/core/math/transform_2d.h index 1ee7d3d8..27eebe1a 100644 --- a/engine/core/math/transform_2d.h +++ b/engine/core/math/transform_2d.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRANSFORM_2D_H -#define TRANSFORM_2D_H +#pragma once #include "core/math/math_funcs.h" #include "core/math/rect2.h" @@ -53,13 +52,17 @@ struct [[nodiscard]] Transform2D { // WARNING: Be aware that unlike 3D code, 2D code uses a left-handed coordinate system: // Y-axis points down, and angle is measure from +X to +Y in a clockwise-fashion. - Vector2 columns[3]; + Vector2 columns[3] = { + { 1, 0 }, + { 0, 1 }, + { 0, 0 }, + }; _FORCE_INLINE_ real_t tdotx(const Vector2 &p_v) const { return columns[0][0] * p_v.x + columns[1][0] * p_v.y; } _FORCE_INLINE_ real_t tdoty(const Vector2 &p_v) const { return columns[0][1] * p_v.x + columns[1][1] * p_v.y; } - const Vector2 &operator[](int p_idx) const { return columns[p_idx]; } - Vector2 &operator[](int p_idx) { return columns[p_idx]; } + constexpr const Vector2 &operator[](int p_idx) const { return columns[p_idx]; } + constexpr Vector2 &operator[](int p_idx) { return columns[p_idx]; } void invert(); Transform2D inverse() const; @@ -101,19 +104,20 @@ struct [[nodiscard]] Transform2D { Transform2D orthonormalized() const; bool is_conformal() const; bool is_equal_approx(const Transform2D &p_transform) const; + bool is_same(const Transform2D &p_transform) const; bool is_finite() const; Transform2D looking_at(const Vector2 &p_target) const; - bool operator==(const Transform2D &p_transform) const; - bool operator!=(const Transform2D &p_transform) const; + constexpr bool operator==(const Transform2D &p_transform) const; + constexpr bool operator!=(const Transform2D &p_transform) const; void operator*=(const Transform2D &p_transform); Transform2D operator*(const Transform2D &p_transform) const; - void operator*=(real_t p_val); - Transform2D operator*(real_t p_val) const; - void operator/=(real_t p_val); - Transform2D operator/(real_t p_val) const; + constexpr void operator*=(real_t p_val); + constexpr Transform2D operator*(real_t p_val) const; + constexpr void operator/=(real_t p_val); + constexpr Transform2D operator/(real_t p_val) const; Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; @@ -128,31 +132,67 @@ struct [[nodiscard]] Transform2D { operator String() const; - Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) { - columns[0][0] = p_xx; - columns[0][1] = p_xy; - columns[1][0] = p_yx; - columns[1][1] = p_yy; - columns[2][0] = p_ox; - columns[2][1] = p_oy; - } + constexpr Transform2D(real_t p_xx, real_t p_xy, real_t p_yx, real_t p_yy, real_t p_ox, real_t p_oy) : + columns{ + { p_xx, p_xy }, + { p_yx, p_yy }, + { p_ox, p_oy }, + } {} - Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) { - columns[0] = p_x; - columns[1] = p_y; - columns[2] = p_origin; - } + constexpr Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) : + columns{ p_x, p_y, p_origin } {} Transform2D(real_t p_rot, const Vector2 &p_pos); Transform2D(real_t p_rot, const Size2 &p_scale, real_t p_skew, const Vector2 &p_pos); - Transform2D() { - columns[0][0] = 1.0; - columns[1][1] = 1.0; - } + Transform2D() = default; }; +constexpr bool Transform2D::operator==(const Transform2D &p_transform) const { + for (int i = 0; i < 3; i++) { + if (columns[i] != p_transform.columns[i]) { + return false; + } + } + + return true; +} + +constexpr bool Transform2D::operator!=(const Transform2D &p_transform) const { + for (int i = 0; i < 3; i++) { + if (columns[i] != p_transform.columns[i]) { + return true; + } + } + + return false; +} + +constexpr void Transform2D::operator*=(real_t p_val) { + columns[0] *= p_val; + columns[1] *= p_val; + columns[2] *= p_val; +} + +constexpr Transform2D Transform2D::operator*(real_t p_val) const { + Transform2D ret(*this); + ret *= p_val; + return ret; +} + +constexpr void Transform2D::operator/=(real_t p_val) { + columns[0] /= p_val; + columns[1] /= p_val; + columns[2] /= p_val; +} + +constexpr Transform2D Transform2D::operator/(real_t p_val) const { + Transform2D ret(*this); + ret /= p_val; + return ret; +} + Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const { return Vector2( tdotx(p_vec), @@ -249,5 +289,3 @@ Vector Transform2D::xform_inv(const Vector &p_array) const { } return array; } - -#endif // TRANSFORM_2D_H diff --git a/engine/core/math/transform_3d.cpp b/engine/core/math/transform_3d.cpp index d4673851..b4d02408 100644 --- a/engine/core/math/transform_3d.cpp +++ b/engine/core/math/transform_3d.cpp @@ -173,18 +173,14 @@ 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 Transform3D::is_same(const Transform3D &p_transform) const { + return basis.is_same(p_transform.basis) && origin.is_same(p_transform.origin); +} + bool Transform3D::is_finite() const { return basis.is_finite() && origin.is_finite(); } -bool Transform3D::operator==(const Transform3D &p_transform) const { - return (basis == p_transform.basis && origin == p_transform.origin); -} - -bool Transform3D::operator!=(const Transform3D &p_transform) const { - return (basis != p_transform.basis || origin != p_transform.origin); -} - void Transform3D::operator*=(const Transform3D &p_transform) { origin = xform(p_transform.origin); basis *= p_transform.basis; @@ -196,48 +192,9 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const { return t; } -void Transform3D::operator*=(real_t p_val) { - origin *= p_val; - basis *= p_val; -} - -Transform3D Transform3D::operator*(real_t p_val) const { - Transform3D ret(*this); - ret *= p_val; - return ret; -} - -void Transform3D::operator/=(real_t p_val) { - basis /= p_val; - origin /= p_val; -} - -Transform3D Transform3D::operator/(real_t p_val) const { - Transform3D ret(*this); - ret /= p_val; - return ret; -} - Transform3D::operator String() const { return "[X: " + basis.get_column(0).operator String() + ", Y: " + basis.get_column(1).operator String() + ", Z: " + basis.get_column(2).operator String() + ", O: " + origin.operator String() + "]"; } - -Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) : - basis(p_basis), - origin(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_column(0, p_x); - basis.set_column(1, p_y); - basis.set_column(2, p_z); -} - -Transform3D::Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) { - basis = Basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz); - origin = Vector3(p_ox, p_oy, p_oz); -} diff --git a/engine/core/math/transform_3d.h b/engine/core/math/transform_3d.h index b1de2334..0d5cbb0f 100644 --- a/engine/core/math/transform_3d.h +++ b/engine/core/math/transform_3d.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRANSFORM_3D_H -#define TRANSFORM_3D_H +#pragma once #include "core/math/aabb.h" #include "core/math/basis.h" @@ -75,10 +74,11 @@ struct [[nodiscard]] Transform3D { void orthogonalize(); Transform3D orthogonalized() const; bool is_equal_approx(const Transform3D &p_transform) const; + bool is_same(const Transform3D &p_transform) const; bool is_finite() const; - bool operator==(const Transform3D &p_transform) const; - bool operator!=(const Transform3D &p_transform) const; + constexpr bool operator==(const Transform3D &p_transform) const; + constexpr bool operator!=(const Transform3D &p_transform) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; @@ -102,10 +102,10 @@ struct [[nodiscard]] Transform3D { void operator*=(const Transform3D &p_transform); Transform3D operator*(const Transform3D &p_transform) const; - void operator*=(real_t p_val); - Transform3D operator*(real_t p_val) const; - void operator/=(real_t p_val); - Transform3D operator/(real_t p_val) const; + constexpr void operator*=(real_t p_val); + constexpr Transform3D operator*(real_t p_val) const; + constexpr void operator/=(real_t p_val); + constexpr Transform3D operator/(real_t p_val) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; @@ -124,12 +124,48 @@ struct [[nodiscard]] Transform3D { operator String() const; - 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 p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz); + Transform3D() = default; + constexpr Transform3D(const Basis &p_basis, const Vector3 &p_origin = Vector3()) : + basis(p_basis), + origin(p_origin) {} + constexpr Transform3D(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) : + basis(p_x, p_y, p_z), + origin(p_origin) {} + constexpr Transform3D(real_t p_xx, real_t p_xy, real_t p_xz, real_t p_yx, real_t p_yy, real_t p_yz, real_t p_zx, real_t p_zy, real_t p_zz, real_t p_ox, real_t p_oy, real_t p_oz) : + basis(p_xx, p_xy, p_xz, p_yx, p_yy, p_yz, p_zx, p_zy, p_zz), + origin(p_ox, p_oy, p_oz) {} }; +constexpr bool Transform3D::operator==(const Transform3D &p_transform) const { + return (basis == p_transform.basis && origin == p_transform.origin); +} + +constexpr bool Transform3D::operator!=(const Transform3D &p_transform) const { + return (basis != p_transform.basis || origin != p_transform.origin); +} + +constexpr void Transform3D::operator*=(real_t p_val) { + origin *= p_val; + basis *= p_val; +} + +constexpr Transform3D Transform3D::operator*(real_t p_val) const { + Transform3D ret(*this); + ret *= p_val; + return ret; +} + +constexpr void Transform3D::operator/=(real_t p_val) { + basis /= p_val; + origin /= p_val; +} + +constexpr Transform3D Transform3D::operator/(real_t p_val) const { + Transform3D ret(*this); + ret /= p_val; + return ret; +} + _FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const { return Vector3( basis[0].dot(p_vector) + origin.x, @@ -269,5 +305,3 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Tra real_t d = normal.dot(point); return Plane(normal, d); } - -#endif // TRANSFORM_3D_H diff --git a/engine/core/math/transform_interpolator.h b/engine/core/math/transform_interpolator.h index cc556707..d80876d9 100644 --- a/engine/core/math/transform_interpolator.h +++ b/engine/core/math/transform_interpolator.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRANSFORM_INTERPOLATOR_H -#define TRANSFORM_INTERPOLATOR_H +#pragma once #include "core/math/math_defs.h" #include "core/math/vector3.h" @@ -91,5 +90,3 @@ public: static Method find_method(const Basis &p_a, const Basis &p_b); }; - -#endif // TRANSFORM_INTERPOLATOR_H diff --git a/engine/core/math/triangle_mesh.cpp b/engine/core/math/triangle_mesh.cpp index 01b73318..3b24b351 100644 --- a/engine/core/math/triangle_mesh.cpp +++ b/engine/core/math/triangle_mesh.cpp @@ -182,7 +182,11 @@ void TriangleMesh::create(const Vector &p_faces, const Vector valid = true; } -bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { +bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -234,6 +238,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en if (r_surf_index) { *r_surf_index = s.surface_index; } + if (r_face_index) { + *r_face_index = b.face_index; + } inters = true; } } @@ -283,7 +290,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en return inters; } -bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { +bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -335,6 +346,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V if (r_surf_index) { *r_surf_index = s.surface_index; } + if (r_face_index) { + *r_face_index = b.face_index; + } inters = true; } } @@ -385,6 +399,10 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V } bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const { + if (!valid) { + return false; + } + uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -503,6 +521,85 @@ Vector TriangleMesh::get_faces() const { return faces; } +bool TriangleMesh::create_from_faces(const Vector &p_faces) { + create(p_faces); + return is_valid(); +} + +Dictionary TriangleMesh::intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const { + if (!valid) { + return Dictionary(); + } + + Vector3 r_point; + Vector3 r_normal; + int32_t r_face_index = -1; + + bool intersected = intersect_segment(p_begin, p_end, r_point, r_normal, nullptr, &r_face_index); + if (!intersected) { + return Dictionary(); + } + + Dictionary result; + result["position"] = r_point; + result["normal"] = r_normal; + result["face_index"] = r_face_index; + + return result; +} + +Dictionary TriangleMesh::intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const { + if (!valid) { + return Dictionary(); + } + + Vector3 r_point; + Vector3 r_normal; + int32_t r_face_index = -1; + + bool intersected = intersect_ray(p_begin, p_dir, r_point, r_normal, nullptr, &r_face_index); + if (!intersected) { + return Dictionary(); + } + + Dictionary result; + result["position"] = r_point; + result["normal"] = r_normal; + result["face_index"] = r_face_index; + + return result; +} + +Vector TriangleMesh::get_faces_scriptwrap() const { + if (!valid) { + return Vector(); + } + + Vector faces; + int ts = triangles.size(); + faces.resize(triangles.size() * 3); + + Vector3 *w = faces.ptrw(); + const Triangle *r = triangles.ptr(); + const Vector3 *rv = vertices.ptr(); + + for (int i = 0; i < ts; i++) { + for (int j = 0; j < 3; j++) { + w[i * 3 + j] = rv[r[i].indices[j]]; + } + } + + return faces; +} + +void TriangleMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("create_from_faces", "faces"), &TriangleMesh::create_from_faces); + ClassDB::bind_method(D_METHOD("get_faces"), &TriangleMesh::get_faces_scriptwrap); + + ClassDB::bind_method(D_METHOD("intersect_segment", "begin", "end"), &TriangleMesh::intersect_segment_scriptwrap); + ClassDB::bind_method(D_METHOD("intersect_ray", "begin", "dir"), &TriangleMesh::intersect_ray_scriptwrap); +} + TriangleMesh::TriangleMesh() { valid = false; max_depth = 0; diff --git a/engine/core/math/triangle_mesh.h b/engine/core/math/triangle_mesh.h index 24fc12dd..65fd0ff9 100644 --- a/engine/core/math/triangle_mesh.h +++ b/engine/core/math/triangle_mesh.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRIANGLE_MESH_H -#define TRIANGLE_MESH_H +#pragma once #include "core/math/face3.h" #include "core/object/ref_counted.h" @@ -41,9 +40,12 @@ public: struct Triangle { Vector3 normal; int indices[3]; - int32_t surface_index; + int32_t surface_index = 0; }; +protected: + static void _bind_methods(); + private: Vector triangles; Vector vertices; @@ -51,10 +53,10 @@ private: struct BVH { AABB aabb; Vector3 center; //used for sorting - int left; - int right; + int left = -1; + int right = -1; - int face_index; + int32_t face_index = -1; }; struct BVHCmpX { @@ -77,13 +79,13 @@ private: int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc); Vector bvh; - int max_depth; - bool valid; + int max_depth = 0; + bool valid = false; public: bool is_valid() const; - bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; - bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; + bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; + bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const; bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const; Vector get_faces() const; @@ -92,7 +94,13 @@ public: void get_indices(Vector *r_triangles_indices) const; void create(const Vector &p_faces, const Vector &p_surface_indices = Vector()); + + // Wrapped functions for compatibility with method bindings + // and user exposed script api that can't use more native types. + bool create_from_faces(const Vector &p_faces); + Dictionary intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const; + Dictionary intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const; + Vector get_faces_scriptwrap() const; + TriangleMesh(); }; - -#endif // TRIANGLE_MESH_H diff --git a/engine/core/math/triangulate.h b/engine/core/math/triangulate.h index 0b88f7ec..87cdbd4f 100644 --- a/engine/core/math/triangulate.h +++ b/engine/core/math/triangulate.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TRIANGULATE_H -#define TRIANGULATE_H +#pragma once #include "core/math/vector2.h" #include "core/templates/vector.h" @@ -58,5 +57,3 @@ public: private: static bool snip(const Vector &p_contour, int u, int v, int w, int n, const Vector &V, bool relaxed); }; - -#endif // TRIANGULATE_H diff --git a/engine/core/math/vector2.cpp b/engine/core/math/vector2.cpp index 0590ee8a..7a51c139 100644 --- a/engine/core/math/vector2.cpp +++ b/engine/core/math/vector2.cpp @@ -194,6 +194,10 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); } +bool Vector2::is_same(const Vector2 &p_v) const { + return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y); +} + bool Vector2::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y); } diff --git a/engine/core/math/vector2.h b/engine/core/math/vector2.h index edb47db6..3f6dbefc 100644 --- a/engine/core/math/vector2.h +++ b/engine/core/math/vector2.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR2_H -#define VECTOR2_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -46,18 +45,19 @@ struct [[nodiscard]] Vector2 { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { - union { - real_t x; - real_t width; - }; - union { - real_t y; - real_t height; - }; + real_t x; + real_t y; + }; + + struct { + real_t width; + real_t height; }; real_t coord[2] = { 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_axis) { @@ -129,35 +129,36 @@ struct [[nodiscard]] Vector2 { Vector2 reflect(const Vector2 &p_normal) const; bool is_equal_approx(const Vector2 &p_v) const; + bool is_same(const Vector2 &p_v) const; bool is_zero_approx() const; bool is_finite() const; - Vector2 operator+(const Vector2 &p_v) const; - void operator+=(const Vector2 &p_v); - Vector2 operator-(const Vector2 &p_v) const; - void operator-=(const Vector2 &p_v); - Vector2 operator*(const Vector2 &p_v1) const; + constexpr Vector2 operator+(const Vector2 &p_v) const; + constexpr void operator+=(const Vector2 &p_v); + constexpr Vector2 operator-(const Vector2 &p_v) const; + constexpr void operator-=(const Vector2 &p_v); + constexpr Vector2 operator*(const Vector2 &p_v1) const; - Vector2 operator*(real_t p_rvalue) const; - void operator*=(real_t p_rvalue); - void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; } + constexpr Vector2 operator*(real_t p_rvalue) const; + constexpr void operator*=(real_t p_rvalue); + constexpr void operator*=(const Vector2 &p_rvalue) { *this = *this * p_rvalue; } - Vector2 operator/(const Vector2 &p_v1) const; + constexpr Vector2 operator/(const Vector2 &p_v1) const; - Vector2 operator/(real_t p_rvalue) const; + constexpr Vector2 operator/(real_t p_rvalue) const; - void operator/=(real_t p_rvalue); - void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; } + constexpr void operator/=(real_t p_rvalue); + constexpr void operator/=(const Vector2 &p_rvalue) { *this = *this / p_rvalue; } - Vector2 operator-() const; + constexpr Vector2 operator-() const; - bool operator==(const Vector2 &p_vec2) const; - bool operator!=(const Vector2 &p_vec2) const; + constexpr bool operator==(const Vector2 &p_vec2) const; + constexpr bool operator!=(const Vector2 &p_vec2) const; - bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } - bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } - bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } + constexpr bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } + constexpr bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } + constexpr bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + constexpr bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } real_t angle() const; static Vector2 from_angle(real_t p_angle); @@ -184,70 +185,71 @@ struct [[nodiscard]] Vector2 { operator String() const; operator Vector2i() const; - _FORCE_INLINE_ Vector2() {} - _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { - x = p_x; - y = p_y; - } + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) + constexpr Vector2() : + x(0), y(0) {} + constexpr Vector2(real_t p_x, real_t p_y) : + x(p_x), y(p_y) {} + // NOLINTEND(cppcoreguidelines-pro-type-member-init) }; _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { return p_vec - *this * (dot(p_vec) - p_d); } -_FORCE_INLINE_ Vector2 Vector2::operator+(const Vector2 &p_v) const { +constexpr Vector2 Vector2::operator+(const Vector2 &p_v) const { return Vector2(x + p_v.x, y + p_v.y); } -_FORCE_INLINE_ void Vector2::operator+=(const Vector2 &p_v) { +constexpr void Vector2::operator+=(const Vector2 &p_v) { x += p_v.x; y += p_v.y; } -_FORCE_INLINE_ Vector2 Vector2::operator-(const Vector2 &p_v) const { +constexpr Vector2 Vector2::operator-(const Vector2 &p_v) const { return Vector2(x - p_v.x, y - p_v.y); } -_FORCE_INLINE_ void Vector2::operator-=(const Vector2 &p_v) { +constexpr void Vector2::operator-=(const Vector2 &p_v) { x -= p_v.x; y -= p_v.y; } -_FORCE_INLINE_ Vector2 Vector2::operator*(const Vector2 &p_v1) const { +constexpr Vector2 Vector2::operator*(const Vector2 &p_v1) const { return Vector2(x * p_v1.x, y * p_v1.y); } -_FORCE_INLINE_ Vector2 Vector2::operator*(real_t p_rvalue) const { +constexpr Vector2 Vector2::operator*(real_t p_rvalue) const { return Vector2(x * p_rvalue, y * p_rvalue); } -_FORCE_INLINE_ void Vector2::operator*=(real_t p_rvalue) { +constexpr void Vector2::operator*=(real_t p_rvalue) { x *= p_rvalue; y *= p_rvalue; } -_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const { +constexpr Vector2 Vector2::operator/(const Vector2 &p_v1) const { return Vector2(x / p_v1.x, y / p_v1.y); } -_FORCE_INLINE_ Vector2 Vector2::operator/(real_t p_rvalue) const { +constexpr Vector2 Vector2::operator/(real_t p_rvalue) const { return Vector2(x / p_rvalue, y / p_rvalue); } -_FORCE_INLINE_ void Vector2::operator/=(real_t p_rvalue) { +constexpr void Vector2::operator/=(real_t p_rvalue) { x /= p_rvalue; y /= p_rvalue; } -_FORCE_INLINE_ Vector2 Vector2::operator-() const { +constexpr Vector2 Vector2::operator-() const { return Vector2(-x, -y); } -_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { +constexpr bool Vector2::operator==(const Vector2 &p_vec2) const { return x == p_vec2.x && y == p_vec2.y; } -_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { +constexpr bool Vector2::operator!=(const Vector2 &p_vec2) const { return x != p_vec2.x || y != p_vec2.y; } @@ -308,23 +310,24 @@ Vector2 Vector2::direction_to(const Vector2 &p_to) const { // Multiplication operators required to workaround issues with LLVM using implicit conversion // to Vector2i instead for integers where it should not. -_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) { +constexpr Vector2 operator*(float p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) { +constexpr Vector2 operator*(double p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { +constexpr Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { +constexpr Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } typedef Vector2 Size2; typedef Vector2 Point2; -#endif // VECTOR2_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/vector2i.cpp b/engine/core/math/vector2i.cpp index 790f5647..cef55185 100644 --- a/engine/core/math/vector2i.cpp +++ b/engine/core/math/vector2i.cpp @@ -65,75 +65,6 @@ double Vector2i::length() const { return Math::sqrt((double)length_squared()); } -Vector2i Vector2i::operator+(const Vector2i &p_v) const { - return Vector2i(x + p_v.x, y + p_v.y); -} - -void Vector2i::operator+=(const Vector2i &p_v) { - x += p_v.x; - y += p_v.y; -} - -Vector2i Vector2i::operator-(const Vector2i &p_v) const { - return Vector2i(x - p_v.x, y - p_v.y); -} - -void Vector2i::operator-=(const Vector2i &p_v) { - x -= p_v.x; - y -= p_v.y; -} - -Vector2i Vector2i::operator*(const Vector2i &p_v1) const { - return Vector2i(x * p_v1.x, y * p_v1.y); -} - -Vector2i Vector2i::operator*(int32_t p_rvalue) const { - return Vector2i(x * p_rvalue, y * p_rvalue); -} - -void Vector2i::operator*=(int32_t p_rvalue) { - x *= p_rvalue; - y *= p_rvalue; -} - -Vector2i Vector2i::operator/(const Vector2i &p_v1) const { - return Vector2i(x / p_v1.x, y / p_v1.y); -} - -Vector2i Vector2i::operator/(int32_t p_rvalue) const { - return Vector2i(x / p_rvalue, y / p_rvalue); -} - -void Vector2i::operator/=(int32_t p_rvalue) { - x /= p_rvalue; - y /= p_rvalue; -} - -Vector2i Vector2i::operator%(const Vector2i &p_v1) const { - return Vector2i(x % p_v1.x, y % p_v1.y); -} - -Vector2i Vector2i::operator%(int32_t p_rvalue) const { - return Vector2i(x % p_rvalue, y % p_rvalue); -} - -void Vector2i::operator%=(int32_t p_rvalue) { - x %= p_rvalue; - y %= p_rvalue; -} - -Vector2i Vector2i::operator-() const { - return Vector2i(-x, -y); -} - -bool Vector2i::operator==(const Vector2i &p_vec2) const { - return x == p_vec2.x && y == p_vec2.y; -} - -bool Vector2i::operator!=(const Vector2i &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} - Vector2i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ")"; } diff --git a/engine/core/math/vector2i.h b/engine/core/math/vector2i.h index fff9b0a6..5ce0b93b 100644 --- a/engine/core/math/vector2i.h +++ b/engine/core/math/vector2i.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR2I_H -#define VECTOR2I_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -46,18 +45,19 @@ struct [[nodiscard]] Vector2i { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { - union { - int32_t x; - int32_t width; - }; - union { - int32_t y; - int32_t height; - }; + int32_t x; + int32_t y; + }; + + struct { + int32_t width; + int32_t height; }; int32_t coord[2] = { 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ int32_t &operator[](int p_axis) { @@ -101,32 +101,32 @@ struct [[nodiscard]] Vector2i { return (p_to - *this).length_squared(); } - Vector2i operator+(const Vector2i &p_v) const; - void operator+=(const Vector2i &p_v); - Vector2i operator-(const Vector2i &p_v) const; - void operator-=(const Vector2i &p_v); - Vector2i operator*(const Vector2i &p_v1) const; + constexpr Vector2i operator+(const Vector2i &p_v) const; + constexpr void operator+=(const Vector2i &p_v); + constexpr Vector2i operator-(const Vector2i &p_v) const; + constexpr void operator-=(const Vector2i &p_v); + constexpr Vector2i operator*(const Vector2i &p_v1) const; - Vector2i operator*(int32_t p_rvalue) const; - void operator*=(int32_t p_rvalue); + constexpr Vector2i operator*(int32_t p_rvalue) const; + constexpr void operator*=(int32_t p_rvalue); - Vector2i operator/(const Vector2i &p_v1) const; - Vector2i operator/(int32_t p_rvalue) const; - void operator/=(int32_t p_rvalue); + constexpr Vector2i operator/(const Vector2i &p_v1) const; + constexpr Vector2i operator/(int32_t p_rvalue) const; + constexpr void operator/=(int32_t p_rvalue); - Vector2i operator%(const Vector2i &p_v1) const; - Vector2i operator%(int32_t p_rvalue) const; - void operator%=(int32_t p_rvalue); + constexpr Vector2i operator%(const Vector2i &p_v1) const; + constexpr Vector2i operator%(int32_t p_rvalue) const; + constexpr void operator%=(int32_t p_rvalue); - Vector2i operator-() const; - bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } + constexpr Vector2i operator-() const; + constexpr bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } + constexpr bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); } - bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } - bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } + constexpr bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); } + constexpr bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } - bool operator==(const Vector2i &p_vec2) const; - bool operator!=(const Vector2i &p_vec2) const; + constexpr bool operator==(const Vector2i &p_vec2) const; + constexpr bool operator!=(const Vector2i &p_vec2) const; int64_t length_squared() const; double length() const; @@ -142,32 +142,103 @@ struct [[nodiscard]] Vector2i { operator String() const; operator Vector2() const; - inline Vector2i() {} - inline Vector2i(int32_t p_x, int32_t p_y) { - x = p_x; - y = p_y; - } + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) + constexpr Vector2i() : + x(0), y(0) {} + constexpr Vector2i(int32_t p_x, int32_t p_y) : + x(p_x), y(p_y) {} + // NOLINTEND(cppcoreguidelines-pro-type-member-init) }; +constexpr Vector2i Vector2i::operator+(const Vector2i &p_v) const { + return Vector2i(x + p_v.x, y + p_v.y); +} + +constexpr void Vector2i::operator+=(const Vector2i &p_v) { + x += p_v.x; + y += p_v.y; +} + +constexpr Vector2i Vector2i::operator-(const Vector2i &p_v) const { + return Vector2i(x - p_v.x, y - p_v.y); +} + +constexpr void Vector2i::operator-=(const Vector2i &p_v) { + x -= p_v.x; + y -= p_v.y; +} + +constexpr Vector2i Vector2i::operator*(const Vector2i &p_v1) const { + return Vector2i(x * p_v1.x, y * p_v1.y); +} + +constexpr Vector2i Vector2i::operator*(int32_t p_rvalue) const { + return Vector2i(x * p_rvalue, y * p_rvalue); +} + +constexpr void Vector2i::operator*=(int32_t p_rvalue) { + x *= p_rvalue; + y *= p_rvalue; +} + +constexpr Vector2i Vector2i::operator/(const Vector2i &p_v1) const { + return Vector2i(x / p_v1.x, y / p_v1.y); +} + +constexpr Vector2i Vector2i::operator/(int32_t p_rvalue) const { + return Vector2i(x / p_rvalue, y / p_rvalue); +} + +constexpr void Vector2i::operator/=(int32_t p_rvalue) { + x /= p_rvalue; + y /= p_rvalue; +} + +constexpr Vector2i Vector2i::operator%(const Vector2i &p_v1) const { + return Vector2i(x % p_v1.x, y % p_v1.y); +} + +constexpr Vector2i Vector2i::operator%(int32_t p_rvalue) const { + return Vector2i(x % p_rvalue, y % p_rvalue); +} + +constexpr void Vector2i::operator%=(int32_t p_rvalue) { + x %= p_rvalue; + y %= p_rvalue; +} + +constexpr Vector2i Vector2i::operator-() const { + return Vector2i(-x, -y); +} + +constexpr bool Vector2i::operator==(const Vector2i &p_vec2) const { + return x == p_vec2.x && y == p_vec2.y; +} + +constexpr bool Vector2i::operator!=(const Vector2i &p_vec2) const { + return x != p_vec2.x || y != p_vec2.y; +} + // Multiplication operators required to workaround issues with LLVM using implicit conversion. -_FORCE_INLINE_ Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) { +constexpr Vector2i operator*(int32_t p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) { +constexpr Vector2i operator*(int64_t p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(float p_scalar, const Vector2i &p_vector) { +constexpr Vector2i operator*(float p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector2i operator*(double p_scalar, const Vector2i &p_vector) { +constexpr Vector2i operator*(double p_scalar, const Vector2i &p_vector) { return p_vector * p_scalar; } typedef Vector2i Size2i; typedef Vector2i Point2i; -#endif // VECTOR2I_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/vector3.cpp b/engine/core/math/vector3.cpp index e18ac3b0..24422c57 100644 --- a/engine/core/math/vector3.cpp +++ b/engine/core/math/vector3.cpp @@ -156,6 +156,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z); } +bool Vector3::is_same(const Vector3 &p_v) const { + return Math::is_same(x, p_v.x) && Math::is_same(y, p_v.y) && Math::is_same(z, p_v.z); +} + bool Vector3::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); } diff --git a/engine/core/math/vector3.h b/engine/core/math/vector3.h index fd0dec35..4ddfac64 100644 --- a/engine/core/math/vector3.h +++ b/engine/core/math/vector3.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR3_H -#define VECTOR3_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -49,6 +48,7 @@ struct [[nodiscard]] Vector3 { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -56,6 +56,7 @@ struct [[nodiscard]] Vector3 { }; real_t coord[3] = { 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const real_t &operator[](int p_axis) const { @@ -156,43 +157,42 @@ struct [[nodiscard]] Vector3 { _FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const; bool is_equal_approx(const Vector3 &p_v) const; + bool is_same(const Vector3 &p_v) const; bool is_zero_approx() const; bool is_finite() const; /* Operators */ - _FORCE_INLINE_ Vector3 &operator+=(const Vector3 &p_v); - _FORCE_INLINE_ Vector3 operator+(const Vector3 &p_v) const; - _FORCE_INLINE_ Vector3 &operator-=(const Vector3 &p_v); - _FORCE_INLINE_ Vector3 operator-(const Vector3 &p_v) const; - _FORCE_INLINE_ Vector3 &operator*=(const Vector3 &p_v); - _FORCE_INLINE_ Vector3 operator*(const Vector3 &p_v) const; - _FORCE_INLINE_ Vector3 &operator/=(const Vector3 &p_v); - _FORCE_INLINE_ Vector3 operator/(const Vector3 &p_v) const; + constexpr Vector3 &operator+=(const Vector3 &p_v); + constexpr Vector3 operator+(const Vector3 &p_v) const; + constexpr Vector3 &operator-=(const Vector3 &p_v); + constexpr Vector3 operator-(const Vector3 &p_v) const; + constexpr Vector3 &operator*=(const Vector3 &p_v); + constexpr Vector3 operator*(const Vector3 &p_v) const; + constexpr Vector3 &operator/=(const Vector3 &p_v); + constexpr Vector3 operator/(const Vector3 &p_v) const; - _FORCE_INLINE_ Vector3 &operator*=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const; - _FORCE_INLINE_ Vector3 &operator/=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const; + constexpr Vector3 &operator*=(real_t p_scalar); + constexpr Vector3 operator*(real_t p_scalar) const; + constexpr Vector3 &operator/=(real_t p_scalar); + constexpr Vector3 operator/(real_t p_scalar) const; - _FORCE_INLINE_ Vector3 operator-() const; + constexpr Vector3 operator-() const; - _FORCE_INLINE_ bool operator==(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator<(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator>(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const; + constexpr bool operator==(const Vector3 &p_v) const; + constexpr bool operator!=(const Vector3 &p_v) const; + constexpr bool operator<(const Vector3 &p_v) const; + constexpr bool operator<=(const Vector3 &p_v) const; + constexpr bool operator>(const Vector3 &p_v) const; + constexpr bool operator>=(const Vector3 &p_v) const; operator String() const; operator Vector3i() const; - _FORCE_INLINE_ Vector3() {} - _FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) { - x = p_x; - y = p_y; - z = p_z; - } + constexpr Vector3() : + x(0), y(0), z(0) {} + constexpr Vector3(real_t p_x, real_t p_y, real_t p_z) : + x(p_x), y(p_y), z(p_z) {} }; Vector3 Vector3::cross(const Vector3 &p_with) const { @@ -339,51 +339,51 @@ Vector3 Vector3::get_any_perpendicular() const { /* Operators */ -Vector3 &Vector3::operator+=(const Vector3 &p_v) { +constexpr Vector3 &Vector3::operator+=(const Vector3 &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; return *this; } -Vector3 Vector3::operator+(const Vector3 &p_v) const { +constexpr Vector3 Vector3::operator+(const Vector3 &p_v) const { return Vector3(x + p_v.x, y + p_v.y, z + p_v.z); } -Vector3 &Vector3::operator-=(const Vector3 &p_v) { +constexpr Vector3 &Vector3::operator-=(const Vector3 &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; return *this; } -Vector3 Vector3::operator-(const Vector3 &p_v) const { +constexpr Vector3 Vector3::operator-(const Vector3 &p_v) const { return Vector3(x - p_v.x, y - p_v.y, z - p_v.z); } -Vector3 &Vector3::operator*=(const Vector3 &p_v) { +constexpr Vector3 &Vector3::operator*=(const Vector3 &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; return *this; } -Vector3 Vector3::operator*(const Vector3 &p_v) const { +constexpr Vector3 Vector3::operator*(const Vector3 &p_v) const { return Vector3(x * p_v.x, y * p_v.y, z * p_v.z); } -Vector3 &Vector3::operator/=(const Vector3 &p_v) { +constexpr Vector3 &Vector3::operator/=(const Vector3 &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; return *this; } -Vector3 Vector3::operator/(const Vector3 &p_v) const { +constexpr Vector3 Vector3::operator/(const Vector3 &p_v) const { return Vector3(x / p_v.x, y / p_v.y, z / p_v.z); } -Vector3 &Vector3::operator*=(real_t p_scalar) { +constexpr Vector3 &Vector3::operator*=(real_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; @@ -393,50 +393,50 @@ Vector3 &Vector3::operator*=(real_t p_scalar) { // Multiplication operators required to workaround issues with LLVM using implicit conversion // to Vector3i instead for integers where it should not. -_FORCE_INLINE_ Vector3 operator*(float p_scalar, const Vector3 &p_vec) { +constexpr Vector3 operator*(float p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector3 operator*(double p_scalar, const Vector3 &p_vec) { +constexpr Vector3 operator*(double p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) { +constexpr Vector3 operator*(int32_t p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) { +constexpr Vector3 operator*(int64_t p_scalar, const Vector3 &p_vec) { return p_vec * p_scalar; } -Vector3 Vector3::operator*(real_t p_scalar) const { +constexpr Vector3 Vector3::operator*(real_t p_scalar) const { return Vector3(x * p_scalar, y * p_scalar, z * p_scalar); } -Vector3 &Vector3::operator/=(real_t p_scalar) { +constexpr Vector3 &Vector3::operator/=(real_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -Vector3 Vector3::operator/(real_t p_scalar) const { +constexpr Vector3 Vector3::operator/(real_t p_scalar) const { return Vector3(x / p_scalar, y / p_scalar, z / p_scalar); } -Vector3 Vector3::operator-() const { +constexpr Vector3 Vector3::operator-() const { return Vector3(-x, -y, -z); } -bool Vector3::operator==(const Vector3 &p_v) const { +constexpr bool Vector3::operator==(const Vector3 &p_v) const { return x == p_v.x && y == p_v.y && z == p_v.z; } -bool Vector3::operator!=(const Vector3 &p_v) const { +constexpr bool Vector3::operator!=(const Vector3 &p_v) const { return x != p_v.x || y != p_v.y || z != p_v.z; } -bool Vector3::operator<(const Vector3 &p_v) const { +constexpr bool Vector3::operator<(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z < p_v.z; @@ -446,7 +446,7 @@ bool Vector3::operator<(const Vector3 &p_v) const { return x < p_v.x; } -bool Vector3::operator>(const Vector3 &p_v) const { +constexpr bool Vector3::operator>(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z > p_v.z; @@ -456,7 +456,7 @@ bool Vector3::operator>(const Vector3 &p_v) const { return x > p_v.x; } -bool Vector3::operator<=(const Vector3 &p_v) const { +constexpr bool Vector3::operator<=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z <= p_v.z; @@ -466,7 +466,7 @@ bool Vector3::operator<=(const Vector3 &p_v) const { return x < p_v.x; } -bool Vector3::operator>=(const Vector3 &p_v) const { +constexpr bool Vector3::operator>=(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z >= p_v.z; @@ -550,4 +550,5 @@ Vector3 Vector3::reflect(const Vector3 &p_normal) const { return 2.0f * p_normal * dot(p_normal) - *this; } -#endif // VECTOR3_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/vector3i.h b/engine/core/math/vector3i.h index 40d0700b..d7d1455e 100644 --- a/engine/core/math/vector3i.h +++ b/engine/core/math/vector3i.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR3I_H -#define VECTOR3I_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -47,6 +46,7 @@ struct [[nodiscard]] Vector3i { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { int32_t x; int32_t y; @@ -54,6 +54,7 @@ struct [[nodiscard]] Vector3i { }; int32_t coord[3] = { 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const int32_t &operator[](int p_axis) const { @@ -102,42 +103,40 @@ struct [[nodiscard]] Vector3i { /* Operators */ - _FORCE_INLINE_ Vector3i &operator+=(const Vector3i &p_v); - _FORCE_INLINE_ Vector3i operator+(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator-=(const Vector3i &p_v); - _FORCE_INLINE_ Vector3i operator-(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator*=(const Vector3i &p_v); - _FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v); - _FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v); - _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const; + constexpr Vector3i &operator+=(const Vector3i &p_v); + constexpr Vector3i operator+(const Vector3i &p_v) const; + constexpr Vector3i &operator-=(const Vector3i &p_v); + constexpr Vector3i operator-(const Vector3i &p_v) const; + constexpr Vector3i &operator*=(const Vector3i &p_v); + constexpr Vector3i operator*(const Vector3i &p_v) const; + constexpr Vector3i &operator/=(const Vector3i &p_v); + constexpr Vector3i operator/(const Vector3i &p_v) const; + constexpr Vector3i &operator%=(const Vector3i &p_v); + constexpr Vector3i operator%(const Vector3i &p_v) const; - _FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const; - _FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const; - _FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar); - _FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const; + constexpr Vector3i &operator*=(int32_t p_scalar); + constexpr Vector3i operator*(int32_t p_scalar) const; + constexpr Vector3i &operator/=(int32_t p_scalar); + constexpr Vector3i operator/(int32_t p_scalar) const; + constexpr Vector3i &operator%=(int32_t p_scalar); + constexpr Vector3i operator%(int32_t p_scalar) const; - _FORCE_INLINE_ Vector3i operator-() const; + constexpr Vector3i operator-() const; - _FORCE_INLINE_ bool operator==(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator<(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator>(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const; + constexpr bool operator==(const Vector3i &p_v) const; + constexpr bool operator!=(const Vector3i &p_v) const; + constexpr bool operator<(const Vector3i &p_v) const; + constexpr bool operator<=(const Vector3i &p_v) const; + constexpr bool operator>(const Vector3i &p_v) const; + constexpr bool operator>=(const Vector3i &p_v) const; operator String() const; operator Vector3() const; - _FORCE_INLINE_ Vector3i() {} - _FORCE_INLINE_ Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) { - x = p_x; - y = p_y; - z = p_z; - } + constexpr Vector3i() : + x(0), y(0), z(0) {} + constexpr Vector3i(int32_t p_x, int32_t p_y, int32_t p_z) : + x(p_x), y(p_y), z(p_z) {} }; int64_t Vector3i::length_squared() const { @@ -166,125 +165,125 @@ int64_t Vector3i::distance_squared_to(const Vector3i &p_to) const { /* Operators */ -Vector3i &Vector3i::operator+=(const Vector3i &p_v) { +constexpr Vector3i &Vector3i::operator+=(const Vector3i &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; return *this; } -Vector3i Vector3i::operator+(const Vector3i &p_v) const { +constexpr Vector3i Vector3i::operator+(const Vector3i &p_v) const { return Vector3i(x + p_v.x, y + p_v.y, z + p_v.z); } -Vector3i &Vector3i::operator-=(const Vector3i &p_v) { +constexpr Vector3i &Vector3i::operator-=(const Vector3i &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; return *this; } -Vector3i Vector3i::operator-(const Vector3i &p_v) const { +constexpr Vector3i Vector3i::operator-(const Vector3i &p_v) const { return Vector3i(x - p_v.x, y - p_v.y, z - p_v.z); } -Vector3i &Vector3i::operator*=(const Vector3i &p_v) { +constexpr Vector3i &Vector3i::operator*=(const Vector3i &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; return *this; } -Vector3i Vector3i::operator*(const Vector3i &p_v) const { +constexpr Vector3i Vector3i::operator*(const Vector3i &p_v) const { return Vector3i(x * p_v.x, y * p_v.y, z * p_v.z); } -Vector3i &Vector3i::operator/=(const Vector3i &p_v) { +constexpr Vector3i &Vector3i::operator/=(const Vector3i &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; return *this; } -Vector3i Vector3i::operator/(const Vector3i &p_v) const { +constexpr Vector3i Vector3i::operator/(const Vector3i &p_v) const { return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z); } -Vector3i &Vector3i::operator%=(const Vector3i &p_v) { +constexpr Vector3i &Vector3i::operator%=(const Vector3i &p_v) { x %= p_v.x; y %= p_v.y; z %= p_v.z; return *this; } -Vector3i Vector3i::operator%(const Vector3i &p_v) const { +constexpr Vector3i Vector3i::operator%(const Vector3i &p_v) const { return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z); } -Vector3i &Vector3i::operator*=(int32_t p_scalar) { +constexpr Vector3i &Vector3i::operator*=(int32_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; return *this; } -Vector3i Vector3i::operator*(int32_t p_scalar) const { +constexpr Vector3i Vector3i::operator*(int32_t p_scalar) const { return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar); } // Multiplication operators required to workaround issues with LLVM using implicit conversion. -_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) { +constexpr Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) { +constexpr Vector3i operator*(int64_t p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector3i operator*(float p_scalar, const Vector3i &p_vector) { +constexpr Vector3i operator*(float p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector3i operator*(double p_scalar, const Vector3i &p_vector) { +constexpr Vector3i operator*(double p_scalar, const Vector3i &p_vector) { return p_vector * p_scalar; } -Vector3i &Vector3i::operator/=(int32_t p_scalar) { +constexpr Vector3i &Vector3i::operator/=(int32_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; return *this; } -Vector3i Vector3i::operator/(int32_t p_scalar) const { +constexpr Vector3i Vector3i::operator/(int32_t p_scalar) const { return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar); } -Vector3i &Vector3i::operator%=(int32_t p_scalar) { +constexpr Vector3i &Vector3i::operator%=(int32_t p_scalar) { x %= p_scalar; y %= p_scalar; z %= p_scalar; return *this; } -Vector3i Vector3i::operator%(int32_t p_scalar) const { +constexpr Vector3i Vector3i::operator%(int32_t p_scalar) const { return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar); } -Vector3i Vector3i::operator-() const { +constexpr Vector3i Vector3i::operator-() const { return Vector3i(-x, -y, -z); } -bool Vector3i::operator==(const Vector3i &p_v) const { +constexpr bool Vector3i::operator==(const Vector3i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z); } -bool Vector3i::operator!=(const Vector3i &p_v) const { +constexpr bool Vector3i::operator!=(const Vector3i &p_v) const { return (x != p_v.x || y != p_v.y || z != p_v.z); } -bool Vector3i::operator<(const Vector3i &p_v) const { +constexpr bool Vector3i::operator<(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z < p_v.z; @@ -296,7 +295,7 @@ bool Vector3i::operator<(const Vector3i &p_v) const { } } -bool Vector3i::operator>(const Vector3i &p_v) const { +constexpr bool Vector3i::operator>(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z > p_v.z; @@ -308,7 +307,7 @@ bool Vector3i::operator>(const Vector3i &p_v) const { } } -bool Vector3i::operator<=(const Vector3i &p_v) const { +constexpr bool Vector3i::operator<=(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z <= p_v.z; @@ -320,7 +319,7 @@ bool Vector3i::operator<=(const Vector3i &p_v) const { } } -bool Vector3i::operator>=(const Vector3i &p_v) const { +constexpr bool Vector3i::operator>=(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { return z >= p_v.z; @@ -336,4 +335,5 @@ void Vector3i::zero() { x = y = z = 0; } -#endif // VECTOR3I_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/vector4.cpp b/engine/core/math/vector4.cpp index 8ac2c4bf..e4fa1769 100644 --- a/engine/core/math/vector4.cpp +++ b/engine/core/math/vector4.cpp @@ -62,6 +62,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } +bool Vector4::is_same(const Vector4 &p_vec4) const { + return Math::is_same(x, p_vec4.x) && Math::is_same(y, p_vec4.y) && Math::is_same(z, p_vec4.z) && Math::is_same(w, p_vec4.w); +} + bool Vector4::is_zero_approx() const { return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); } diff --git a/engine/core/math/vector4.h b/engine/core/math/vector4.h index 9197e358..c8356413 100644 --- a/engine/core/math/vector4.h +++ b/engine/core/math/vector4.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR4_H -#define VECTOR4_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_defs.h" @@ -49,6 +48,7 @@ struct [[nodiscard]] Vector4 { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { real_t x; real_t y; @@ -56,6 +56,7 @@ struct [[nodiscard]] Vector4 { real_t w; }; real_t coord[4] = { 0, 0, 0, 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ real_t &operator[](int p_axis) { @@ -89,6 +90,7 @@ struct [[nodiscard]] Vector4 { _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; bool is_zero_approx() const; + bool is_same(const Vector4 &p_vec4) const; bool is_finite() const; real_t length() const; void normalize(); @@ -120,37 +122,34 @@ struct [[nodiscard]] Vector4 { Vector4 inverse() const; _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; - _FORCE_INLINE_ void operator+=(const Vector4 &p_vec4); - _FORCE_INLINE_ void operator-=(const Vector4 &p_vec4); - _FORCE_INLINE_ void operator*=(const Vector4 &p_vec4); - _FORCE_INLINE_ void operator/=(const Vector4 &p_vec4); - _FORCE_INLINE_ void operator*=(real_t p_s); - _FORCE_INLINE_ void operator/=(real_t p_s); - _FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const; - _FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const; - _FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const; - _FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const; - _FORCE_INLINE_ Vector4 operator-() const; - _FORCE_INLINE_ Vector4 operator*(real_t p_s) const; - _FORCE_INLINE_ Vector4 operator/(real_t p_s) const; + constexpr void operator+=(const Vector4 &p_vec4); + constexpr void operator-=(const Vector4 &p_vec4); + constexpr void operator*=(const Vector4 &p_vec4); + constexpr void operator/=(const Vector4 &p_vec4); + constexpr void operator*=(real_t p_s); + constexpr void operator/=(real_t p_s); + constexpr Vector4 operator+(const Vector4 &p_vec4) const; + constexpr Vector4 operator-(const Vector4 &p_vec4) const; + constexpr Vector4 operator*(const Vector4 &p_vec4) const; + constexpr Vector4 operator/(const Vector4 &p_vec4) const; + constexpr Vector4 operator-() const; + constexpr Vector4 operator*(real_t p_s) const; + constexpr Vector4 operator/(real_t p_s) const; - _FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; + constexpr bool operator==(const Vector4 &p_vec4) const; + constexpr bool operator!=(const Vector4 &p_vec4) const; + constexpr bool operator>(const Vector4 &p_vec4) const; + constexpr bool operator<(const Vector4 &p_vec4) const; + constexpr bool operator>=(const Vector4 &p_vec4) const; + constexpr bool operator<=(const Vector4 &p_vec4) const; operator String() const; operator Vector4i() const; - _FORCE_INLINE_ Vector4() {} - _FORCE_INLINE_ Vector4(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; - } + constexpr Vector4() : + x(0), y(0), z(0), w(0) {} + constexpr Vector4(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) {} }; real_t Vector4::dot(const Vector4 &p_vec4) const { @@ -161,81 +160,81 @@ real_t Vector4::length_squared() const { return dot(*this); } -void Vector4::operator+=(const Vector4 &p_vec4) { +constexpr void Vector4::operator+=(const Vector4 &p_vec4) { x += p_vec4.x; y += p_vec4.y; z += p_vec4.z; w += p_vec4.w; } -void Vector4::operator-=(const Vector4 &p_vec4) { +constexpr void Vector4::operator-=(const Vector4 &p_vec4) { x -= p_vec4.x; y -= p_vec4.y; z -= p_vec4.z; w -= p_vec4.w; } -void Vector4::operator*=(const Vector4 &p_vec4) { +constexpr void Vector4::operator*=(const Vector4 &p_vec4) { x *= p_vec4.x; y *= p_vec4.y; z *= p_vec4.z; w *= p_vec4.w; } -void Vector4::operator/=(const Vector4 &p_vec4) { +constexpr void Vector4::operator/=(const Vector4 &p_vec4) { x /= p_vec4.x; y /= p_vec4.y; z /= p_vec4.z; w /= p_vec4.w; } -void Vector4::operator*=(real_t p_s) { +constexpr void Vector4::operator*=(real_t p_s) { x *= p_s; y *= p_s; z *= p_s; w *= p_s; } -void Vector4::operator/=(real_t p_s) { - *this *= 1.0f / p_s; +constexpr void Vector4::operator/=(real_t p_s) { + *this *= (1 / p_s); } -Vector4 Vector4::operator+(const Vector4 &p_vec4) const { +constexpr Vector4 Vector4::operator+(const Vector4 &p_vec4) const { return Vector4(x + p_vec4.x, y + p_vec4.y, z + p_vec4.z, w + p_vec4.w); } -Vector4 Vector4::operator-(const Vector4 &p_vec4) const { +constexpr Vector4 Vector4::operator-(const Vector4 &p_vec4) const { return Vector4(x - p_vec4.x, y - p_vec4.y, z - p_vec4.z, w - p_vec4.w); } -Vector4 Vector4::operator*(const Vector4 &p_vec4) const { +constexpr Vector4 Vector4::operator*(const Vector4 &p_vec4) const { return Vector4(x * p_vec4.x, y * p_vec4.y, z * p_vec4.z, w * p_vec4.w); } -Vector4 Vector4::operator/(const Vector4 &p_vec4) const { +constexpr Vector4 Vector4::operator/(const Vector4 &p_vec4) const { return Vector4(x / p_vec4.x, y / p_vec4.y, z / p_vec4.z, w / p_vec4.w); } -Vector4 Vector4::operator-() const { +constexpr Vector4 Vector4::operator-() const { return Vector4(-x, -y, -z, -w); } -Vector4 Vector4::operator*(real_t p_s) const { +constexpr Vector4 Vector4::operator*(real_t p_s) const { return Vector4(x * p_s, y * p_s, z * p_s, w * p_s); } -Vector4 Vector4::operator/(real_t p_s) const { - return *this * (1.0f / p_s); +constexpr Vector4 Vector4::operator/(real_t p_s) const { + return *this * (1 / p_s); } -bool Vector4::operator==(const Vector4 &p_vec4) const { +constexpr bool Vector4::operator==(const Vector4 &p_vec4) const { return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w; } -bool Vector4::operator!=(const Vector4 &p_vec4) const { +constexpr bool Vector4::operator!=(const Vector4 &p_vec4) const { return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w; } -bool Vector4::operator<(const Vector4 &p_v) const { +constexpr bool Vector4::operator<(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -248,7 +247,7 @@ bool Vector4::operator<(const Vector4 &p_v) const { return x < p_v.x; } -bool Vector4::operator>(const Vector4 &p_v) const { +constexpr bool Vector4::operator>(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -261,7 +260,7 @@ bool Vector4::operator>(const Vector4 &p_v) const { return x > p_v.x; } -bool Vector4::operator<=(const Vector4 &p_v) const { +constexpr bool Vector4::operator<=(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -274,7 +273,7 @@ bool Vector4::operator<=(const Vector4 &p_v) const { return x < p_v.x; } -bool Vector4::operator>=(const Vector4 &p_v) const { +constexpr bool Vector4::operator>=(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -287,20 +286,21 @@ bool Vector4::operator>=(const Vector4 &p_v) const { return x > p_v.x; } -_FORCE_INLINE_ Vector4 operator*(float p_scalar, const Vector4 &p_vec) { +constexpr Vector4 operator*(float p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector4 operator*(double p_scalar, const Vector4 &p_vec) { +constexpr Vector4 operator*(double p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) { +constexpr Vector4 operator*(int32_t p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -_FORCE_INLINE_ Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) { +constexpr Vector4 operator*(int64_t p_scalar, const Vector4 &p_vec) { return p_vec * p_scalar; } -#endif // VECTOR4_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/math/vector4i.h b/engine/core/math/vector4i.h index a9036d68..56ae3f22 100644 --- a/engine/core/math/vector4i.h +++ b/engine/core/math/vector4i.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VECTOR4I_H -#define VECTOR4I_H +#pragma once #include "core/error/error_macros.h" #include "core/math/math_funcs.h" @@ -48,6 +47,7 @@ struct [[nodiscard]] Vector4i { }; union { + // NOLINTBEGIN(modernize-use-default-member-init) struct { int32_t x; int32_t y; @@ -56,6 +56,7 @@ struct [[nodiscard]] Vector4i { }; int32_t coord[4] = { 0 }; + // NOLINTEND(modernize-use-default-member-init) }; _FORCE_INLINE_ const int32_t &operator[](int p_axis) const { @@ -104,44 +105,41 @@ struct [[nodiscard]] Vector4i { /* Operators */ - _FORCE_INLINE_ Vector4i &operator+=(const Vector4i &p_v); - _FORCE_INLINE_ Vector4i operator+(const Vector4i &p_v) const; - _FORCE_INLINE_ Vector4i &operator-=(const Vector4i &p_v); - _FORCE_INLINE_ Vector4i operator-(const Vector4i &p_v) const; - _FORCE_INLINE_ Vector4i &operator*=(const Vector4i &p_v); - _FORCE_INLINE_ Vector4i operator*(const Vector4i &p_v) const; - _FORCE_INLINE_ Vector4i &operator/=(const Vector4i &p_v); - _FORCE_INLINE_ Vector4i operator/(const Vector4i &p_v) const; - _FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v); - _FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const; + constexpr Vector4i &operator+=(const Vector4i &p_v); + constexpr Vector4i operator+(const Vector4i &p_v) const; + constexpr Vector4i &operator-=(const Vector4i &p_v); + constexpr Vector4i operator-(const Vector4i &p_v) const; + constexpr Vector4i &operator*=(const Vector4i &p_v); + constexpr Vector4i operator*(const Vector4i &p_v) const; + constexpr Vector4i &operator/=(const Vector4i &p_v); + constexpr Vector4i operator/(const Vector4i &p_v) const; + constexpr Vector4i &operator%=(const Vector4i &p_v); + constexpr Vector4i operator%(const Vector4i &p_v) const; - _FORCE_INLINE_ Vector4i &operator*=(int32_t p_scalar); - _FORCE_INLINE_ Vector4i operator*(int32_t p_scalar) const; - _FORCE_INLINE_ Vector4i &operator/=(int32_t p_scalar); - _FORCE_INLINE_ Vector4i operator/(int32_t p_scalar) const; - _FORCE_INLINE_ Vector4i &operator%=(int32_t p_scalar); - _FORCE_INLINE_ Vector4i operator%(int32_t p_scalar) const; + constexpr Vector4i &operator*=(int32_t p_scalar); + constexpr Vector4i operator*(int32_t p_scalar) const; + constexpr Vector4i &operator/=(int32_t p_scalar); + constexpr Vector4i operator/(int32_t p_scalar) const; + constexpr Vector4i &operator%=(int32_t p_scalar); + constexpr Vector4i operator%(int32_t p_scalar) const; - _FORCE_INLINE_ Vector4i operator-() const; + constexpr Vector4i operator-() const; - _FORCE_INLINE_ bool operator==(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator<(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator>(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator>=(const Vector4i &p_v) const; + constexpr bool operator==(const Vector4i &p_v) const; + constexpr bool operator!=(const Vector4i &p_v) const; + constexpr bool operator<(const Vector4i &p_v) const; + constexpr bool operator<=(const Vector4i &p_v) const; + constexpr bool operator>(const Vector4i &p_v) const; + constexpr bool operator>=(const Vector4i &p_v) const; operator String() const; operator Vector4() const; - _FORCE_INLINE_ Vector4i() {} + constexpr Vector4i() : + x(0), y(0), z(0), w(0) {} Vector4i(const Vector4 &p_vec4); - _FORCE_INLINE_ Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) { - x = p_x; - y = p_y; - z = p_z; - w = p_w; - } + constexpr Vector4i(int32_t p_x, int32_t p_y, int32_t p_z, int32_t p_w) : + x(p_x), y(p_y), z(p_z), w(p_w) {} }; int64_t Vector4i::length_squared() const { @@ -170,7 +168,7 @@ Vector4i Vector4i::sign() const { /* Operators */ -Vector4i &Vector4i::operator+=(const Vector4i &p_v) { +constexpr Vector4i &Vector4i::operator+=(const Vector4i &p_v) { x += p_v.x; y += p_v.y; z += p_v.z; @@ -178,11 +176,11 @@ Vector4i &Vector4i::operator+=(const Vector4i &p_v) { return *this; } -Vector4i Vector4i::operator+(const Vector4i &p_v) const { +constexpr Vector4i Vector4i::operator+(const Vector4i &p_v) const { return Vector4i(x + p_v.x, y + p_v.y, z + p_v.z, w + p_v.w); } -Vector4i &Vector4i::operator-=(const Vector4i &p_v) { +constexpr Vector4i &Vector4i::operator-=(const Vector4i &p_v) { x -= p_v.x; y -= p_v.y; z -= p_v.z; @@ -190,11 +188,11 @@ Vector4i &Vector4i::operator-=(const Vector4i &p_v) { return *this; } -Vector4i Vector4i::operator-(const Vector4i &p_v) const { +constexpr Vector4i Vector4i::operator-(const Vector4i &p_v) const { return Vector4i(x - p_v.x, y - p_v.y, z - p_v.z, w - p_v.w); } -Vector4i &Vector4i::operator*=(const Vector4i &p_v) { +constexpr Vector4i &Vector4i::operator*=(const Vector4i &p_v) { x *= p_v.x; y *= p_v.y; z *= p_v.z; @@ -202,11 +200,11 @@ Vector4i &Vector4i::operator*=(const Vector4i &p_v) { return *this; } -Vector4i Vector4i::operator*(const Vector4i &p_v) const { +constexpr Vector4i Vector4i::operator*(const Vector4i &p_v) const { return Vector4i(x * p_v.x, y * p_v.y, z * p_v.z, w * p_v.w); } -Vector4i &Vector4i::operator/=(const Vector4i &p_v) { +constexpr Vector4i &Vector4i::operator/=(const Vector4i &p_v) { x /= p_v.x; y /= p_v.y; z /= p_v.z; @@ -214,11 +212,11 @@ Vector4i &Vector4i::operator/=(const Vector4i &p_v) { return *this; } -Vector4i Vector4i::operator/(const Vector4i &p_v) const { +constexpr Vector4i Vector4i::operator/(const Vector4i &p_v) const { return Vector4i(x / p_v.x, y / p_v.y, z / p_v.z, w / p_v.w); } -Vector4i &Vector4i::operator%=(const Vector4i &p_v) { +constexpr Vector4i &Vector4i::operator%=(const Vector4i &p_v) { x %= p_v.x; y %= p_v.y; z %= p_v.z; @@ -226,11 +224,11 @@ Vector4i &Vector4i::operator%=(const Vector4i &p_v) { return *this; } -Vector4i Vector4i::operator%(const Vector4i &p_v) const { +constexpr Vector4i Vector4i::operator%(const Vector4i &p_v) const { return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w); } -Vector4i &Vector4i::operator*=(int32_t p_scalar) { +constexpr Vector4i &Vector4i::operator*=(int32_t p_scalar) { x *= p_scalar; y *= p_scalar; z *= p_scalar; @@ -238,29 +236,29 @@ Vector4i &Vector4i::operator*=(int32_t p_scalar) { return *this; } -Vector4i Vector4i::operator*(int32_t p_scalar) const { +constexpr Vector4i Vector4i::operator*(int32_t p_scalar) const { return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar); } // Multiplication operators required to workaround issues with LLVM using implicit conversion. -_FORCE_INLINE_ Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) { +constexpr Vector4i operator*(int32_t p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) { +constexpr Vector4i operator*(int64_t p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector4i operator*(float p_scalar, const Vector4i &p_vector) { +constexpr Vector4i operator*(float p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -_FORCE_INLINE_ Vector4i operator*(double p_scalar, const Vector4i &p_vector) { +constexpr Vector4i operator*(double p_scalar, const Vector4i &p_vector) { return p_vector * p_scalar; } -Vector4i &Vector4i::operator/=(int32_t p_scalar) { +constexpr Vector4i &Vector4i::operator/=(int32_t p_scalar) { x /= p_scalar; y /= p_scalar; z /= p_scalar; @@ -268,11 +266,11 @@ Vector4i &Vector4i::operator/=(int32_t p_scalar) { return *this; } -Vector4i Vector4i::operator/(int32_t p_scalar) const { +constexpr Vector4i Vector4i::operator/(int32_t p_scalar) const { return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar); } -Vector4i &Vector4i::operator%=(int32_t p_scalar) { +constexpr Vector4i &Vector4i::operator%=(int32_t p_scalar) { x %= p_scalar; y %= p_scalar; z %= p_scalar; @@ -280,23 +278,23 @@ Vector4i &Vector4i::operator%=(int32_t p_scalar) { return *this; } -Vector4i Vector4i::operator%(int32_t p_scalar) const { +constexpr Vector4i Vector4i::operator%(int32_t p_scalar) const { return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar); } -Vector4i Vector4i::operator-() const { +constexpr Vector4i Vector4i::operator-() const { return Vector4i(-x, -y, -z, -w); } -bool Vector4i::operator==(const Vector4i &p_v) const { +constexpr bool Vector4i::operator==(const Vector4i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w); } -bool Vector4i::operator!=(const Vector4i &p_v) const { +constexpr bool Vector4i::operator!=(const Vector4i &p_v) const { return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w); } -bool Vector4i::operator<(const Vector4i &p_v) const { +constexpr bool Vector4i::operator<(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -312,7 +310,7 @@ bool Vector4i::operator<(const Vector4i &p_v) const { } } -bool Vector4i::operator>(const Vector4i &p_v) const { +constexpr bool Vector4i::operator>(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -328,7 +326,7 @@ bool Vector4i::operator>(const Vector4i &p_v) const { } } -bool Vector4i::operator<=(const Vector4i &p_v) const { +constexpr bool Vector4i::operator<=(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -344,7 +342,7 @@ bool Vector4i::operator<=(const Vector4i &p_v) const { } } -bool Vector4i::operator>=(const Vector4i &p_v) const { +constexpr bool Vector4i::operator>=(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { if (z == p_v.z) { @@ -364,4 +362,5 @@ void Vector4i::zero() { x = y = z = w = 0; } -#endif // VECTOR4I_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/object/callable_method_pointer.h b/engine/core/object/callable_method_pointer.h index a12db51c..7462316d 100644 --- a/engine/core/object/callable_method_pointer.h +++ b/engine/core/object/callable_method_pointer.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CALLABLE_METHOD_POINTER_H -#define CALLABLE_METHOD_POINTER_H +#pragma once #include "core/object/object.h" #include "core/variant/binder_common.h" @@ -82,8 +81,7 @@ class CallableCustomMethodPointer : public CallableCustomMethodPointerBase { struct Data { T *instance; uint64_t object_id; - R(T::*method) - (P...); + R (T::*method)(P...); } data; public: @@ -152,8 +150,7 @@ class CallableCustomMethodPointerC : public CallableCustomMethodPointerBase { struct Data { T *instance; uint64_t object_id; - R(T::*method) - (P...) const; + R (T::*method)(P...) const; } data; public: @@ -226,8 +223,7 @@ Callable create_custom_callable_function_pointer(T *p_instance, template class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase { struct Data { - R(*method) - (P...); + R (*method)(P...); } data; public: @@ -292,5 +288,3 @@ Callable create_custom_callable_static_function_pointer( #else #define callable_mp_static(M) create_custom_callable_static_function_pointer(M) #endif - -#endif // CALLABLE_METHOD_POINTER_H diff --git a/engine/core/object/class_db.cpp b/engine/core/object/class_db.cpp index e6536fe8..fbc5fcda 100644 --- a/engine/core/object/class_db.cpp +++ b/engine/core/object/class_db.cpp @@ -35,9 +35,6 @@ #include "core/object/script_language.h" #include "core/version.h" -#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock); -#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock); - #ifdef DEBUG_METHODS_ENABLED MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint32_t p_argcount) { @@ -238,13 +235,13 @@ bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_in } bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); return _is_parent_class(p_class, p_inherits); } void ClassDB::get_class_list(List *p_classes) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); for (const KeyValue &E : classes) { p_classes->push_back(E.key); @@ -255,7 +252,7 @@ void ClassDB::get_class_list(List *p_classes) { #ifdef TOOLS_ENABLED void ClassDB::get_extensions_class_list(List *p_classes) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); for (const KeyValue &E : classes) { if (E.value.api != API_EXTENSION && E.value.api != API_EDITOR_EXTENSION) { @@ -268,7 +265,7 @@ void ClassDB::get_extensions_class_list(List *p_classes) { } void ClassDB::get_extension_class_list(const Ref &p_extension, List *p_classes) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); for (const KeyValue &E : classes) { if (E.value.api != API_EXTENSION && E.value.api != API_EDITOR_EXTENSION) { @@ -284,28 +281,28 @@ void ClassDB::get_extension_class_list(const Ref &p_extension, List } #endif -void ClassDB::get_inheriters_from_class(const StringName &p_class, List *p_classes) { - OBJTYPE_RLOCK; +void ClassDB::get_inheriters_from_class(const StringName &p_class, LocalVector &p_classes) { + Locker::Lock lock(Locker::STATE_READ); for (const KeyValue &E : classes) { if (E.key != p_class && _is_parent_class(E.key, p_class)) { - p_classes->push_back(E.key); + p_classes.push_back(E.key); } } } void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List *p_classes) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); for (const KeyValue &E : classes) { - if (E.key != p_class && _get_parent_class(E.key) == p_class) { + if (E.value.inherits == p_class) { p_classes->push_back(E.key); } } } StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -315,7 +312,7 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { } bool ClassDB::get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *start = classes.getptr(p_class); if (!start) { @@ -356,13 +353,13 @@ StringName ClassDB::_get_parent_class(const StringName &p_class) { } StringName ClassDB::get_parent_class(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); return _get_parent_class(p_class); } ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); @@ -372,13 +369,13 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { uint32_t ClassDB::get_api_hash(APIType p_api) { #ifdef DEBUG_METHODS_ENABLED - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); if (api_hashes_cache.has(p_api)) { return api_hashes_cache[p_api]; } - uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); + uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(GODOT_VERSION_FULL_CONFIG)); List class_list; for (const KeyValue &E : classes) { @@ -520,12 +517,12 @@ uint32_t ClassDB::get_api_hash(APIType p_api) { } bool ClassDB::class_exists(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); return classes.has(p_class); } void ClassDB::add_compatibility_class(const StringName &p_class, const StringName &p_fallback) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); compat_classes[p_class] = p_fallback; } @@ -536,18 +533,21 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) { return StringName(); } -Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) { +Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize, bool p_exposed_only) { ClassInfo *ti; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ti = classes.getptr(p_class); - if (!_can_instantiate(ti)) { + if (!_can_instantiate(ti, p_exposed_only)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } } ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); + if (p_exposed_only) { + ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); + } ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, vformat("Class '%s' or its base class cannot be instantiated.", String(p_class))); } @@ -599,11 +599,15 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require } } -bool ClassDB::_can_instantiate(ClassInfo *p_class_info) { +bool ClassDB::_can_instantiate(ClassInfo *p_class_info, bool p_exposed_only) { if (!p_class_info) { return false; } + if (p_exposed_only && !p_class_info->exposed) { + return false; + } + if (p_class_info->disabled || !p_class_info->creation_func) { return false; } @@ -645,7 +649,7 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) ClassInfo *ti; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ti = classes.getptr(p_class); if (!_can_instantiate(ti)) { if (compat_classes.has(p_class)) { @@ -730,7 +734,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & ERR_FAIL_NULL(p_object); ClassInfo *ti; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ti = classes.getptr(p_class); if (!_can_instantiate(ti)) { if (compat_classes.has(p_class)) { @@ -755,7 +759,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & bool ClassDB::can_instantiate(const StringName &p_class) { String script_path; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -781,7 +785,7 @@ use_script: bool ClassDB::is_abstract(const StringName &p_class) { String script_path; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -813,7 +817,7 @@ use_script: bool ClassDB::is_virtual(const StringName &p_class) { String script_path; { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); if (!ti) { @@ -836,8 +840,8 @@ use_script: return scr.is_valid() && scr->is_valid() && scr->is_abstract(); } -void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { - OBJTYPE_WLOCK; +void ClassDB::_add_class(const StringName &p_class, const StringName &p_inherits) { + Locker::Lock lock(Locker::STATE_WRITE); const StringName &name = p_class; @@ -880,7 +884,7 @@ static MethodInfo info_from_bind(MethodBind *p_method) { } void ClassDB::get_method_list(const StringName &p_class, List *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -926,7 +930,7 @@ void ClassDB::get_method_list(const StringName &p_class, List *p_met } void ClassDB::get_method_list_with_compatibility(const StringName &p_class, List> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -986,7 +990,7 @@ void ClassDB::get_method_list_with_compatibility(const StringName &p_class, List } bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1036,7 +1040,7 @@ bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_met } MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_name) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1051,7 +1055,7 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_n } Vector ClassDB::get_method_compatibility_hashes(const StringName &p_class, const StringName &p_name) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1070,7 +1074,7 @@ Vector ClassDB::get_method_compatibility_hashes(const StringName &p_cl } MethodBind *ClassDB::get_method_with_compatibility(const StringName &p_class, const StringName &p_name, uint64_t p_hash, bool *r_method_exists, bool *r_is_deprecated) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1105,7 +1109,7 @@ MethodBind *ClassDB::get_method_with_compatibility(const StringName &p_class, co } void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); @@ -1142,7 +1146,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName } void ClassDB::get_integer_constant_list(const StringName &p_class, List *p_constants, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1167,7 +1171,7 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List } int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1191,7 +1195,7 @@ int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringNam } bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1210,7 +1214,7 @@ bool ClassDB::has_integer_constant(const StringName &p_class, const StringName & } StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1234,7 +1238,7 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S } void ClassDB::get_enum_list(const StringName &p_class, List *p_enums, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1252,7 +1256,7 @@ void ClassDB::get_enum_list(const StringName &p_class, List *p_enums } void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List *p_constants, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1275,7 +1279,7 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_ void ClassDB::set_method_error_return_values(const StringName &p_class, const StringName &p_method, const Vector &p_values) { #ifdef DEBUG_METHODS_ENABLED - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1286,7 +1290,7 @@ void ClassDB::set_method_error_return_values(const StringName &p_class, const St Vector ClassDB::get_method_error_return_values(const StringName &p_class, const StringName &p_method) { #ifdef DEBUG_METHODS_ENABLED - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL_V(type, Vector()); @@ -1301,7 +1305,7 @@ Vector ClassDB::get_method_error_return_values(const StringName &p_class, } bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1320,7 +1324,7 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool } bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1339,7 +1343,7 @@ bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_na } void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1358,7 +1362,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) } void ClassDB::get_signal_list(const StringName &p_class, List *p_signals, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1379,7 +1383,7 @@ void ClassDB::get_signal_list(const StringName &p_class, List *p_sig } bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1396,7 +1400,7 @@ bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, } bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1413,7 +1417,7 @@ bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, } void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix, int p_indent_depth) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1426,7 +1430,7 @@ void ClassDB::add_property_group(const StringName &p_class, const String &p_name } void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix, int p_indent_depth) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1443,7 +1447,7 @@ void ClassDB::add_property_array_count(const StringName &p_class, const String & } void ClassDB::add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_prefix) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1452,9 +1456,9 @@ void ClassDB::add_property_array(const StringName &p_class, const StringName &p_ // NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end. void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { - lock.read_lock(); + Locker::Lock lock(Locker::STATE_WRITE); + ClassInfo *type = classes.getptr(p_class); - lock.read_unlock(); ERR_FAIL_NULL(type); @@ -1486,8 +1490,6 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), vformat("Object '%s' already has property '%s'.", p_class, p_pinfo.name)); #endif - OBJTYPE_WLOCK - type->property_list.push_back(p_pinfo); type->property_map[p_pinfo.name] = p_pinfo; #ifdef DEBUG_METHODS_ENABLED @@ -1518,7 +1520,7 @@ void ClassDB::set_property_default_value(const StringName &p_class, const String void ClassDB::add_linked_property(const StringName &p_class, const String &p_property, const String &p_linked_property) { #ifdef TOOLS_ENABLED - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); @@ -1534,7 +1536,7 @@ void ClassDB::add_linked_property(const StringName &p_class, const String &p_pro } void ClassDB::get_property_list(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -1577,7 +1579,7 @@ void ClassDB::get_linked_properties_info(const StringName &p_class, const String } bool ClassDB::get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *check = classes.getptr(p_class); while (check) { @@ -1800,7 +1802,7 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper } void ClassDB::set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; ERR_FAIL_NULL(check); @@ -1825,7 +1827,7 @@ bool ClassDB::has_method(const StringName &p_class, const StringName &p_method, } int ClassDB::get_method_argument_count(const StringName &p_class, const StringName &p_method, bool *r_is_valid, bool p_no_inheritance) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -1864,7 +1866,7 @@ void ClassDB::_bind_compatibility(ClassInfo *type, MethodBind *p_method) { } void ClassDB::_bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); StringName method_name = p_method->get_name(); @@ -1933,7 +1935,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ StringName mdname = StaticCString::create(method_name); #endif - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ERR_FAIL_NULL_V(p_bind, nullptr); p_bind->set_name(mdname); @@ -1996,7 +1998,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector &p_arg_names, bool p_object_core) { ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); #ifdef DEBUG_METHODS_ENABLED MethodInfo mi = p_method; @@ -2011,9 +2013,8 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ if (p_arg_names.size() != mi.arguments.size()) { WARN_PRINT(vformat("Mismatch argument name count for virtual method: '%s::%s'.", String(p_class), p_method.name)); } else { - List::Iterator itr = mi.arguments.begin(); - for (int i = 0; i < p_arg_names.size(); ++itr, ++i) { - itr->name = p_arg_names[i]; + for (int64_t i = 0; i < p_arg_names.size(); ++i) { + mi.arguments.write[i].name = p_arg_names[i]; } } } @@ -2031,7 +2032,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ void ClassDB::add_virtual_compatibility_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector &p_arg_names, bool p_object_core) { ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); HashMap> &virtual_methods_compat = classes[p_class].virtual_methods_compat; @@ -2066,7 +2067,7 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List *p } Vector ClassDB::get_virtual_method_compatibility_hashes(const StringName &p_class, const StringName &p_name) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); @@ -2107,14 +2108,14 @@ void ClassDB::add_extension_class_virtual_method(const StringName &p_class, cons } void ClassDB::set_class_enabled(const StringName &p_class, bool p_enable) { - OBJTYPE_WLOCK; + Locker::Lock lock(Locker::STATE_WRITE); ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); classes[p_class].disabled = !p_enable; } bool ClassDB::is_class_enabled(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); if (!ti || !ti->creation_func) { @@ -2128,7 +2129,7 @@ bool ClassDB::is_class_enabled(const StringName &p_class) { } bool ClassDB::is_class_exposed(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2136,7 +2137,7 @@ bool ClassDB::is_class_exposed(const StringName &p_class) { } bool ClassDB::is_class_reloadable(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2144,7 +2145,7 @@ bool ClassDB::is_class_reloadable(const StringName &p_class) { } bool ClassDB::is_class_runtime(const StringName &p_class) { - OBJTYPE_RLOCK; + Locker::Lock lock(Locker::STATE_READ); ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); @@ -2342,7 +2343,9 @@ uint64_t ClassDB::get_native_struct_size(const StringName &p_name) { return native_structs[p_name].struct_size; } -RWLock ClassDB::lock; +Object *ClassDB::_instantiate_allow_unexposed(const StringName &p_class) { + return _instantiate_internal(p_class, false, true, false); +} void ClassDB::cleanup_defaults() { default_values.clear(); @@ -2379,3 +2382,32 @@ bool ClassDB::is_default_array_arg(const Array &p_array) { } // + +ClassDB::Locker::Lock::Lock(Locker::State p_state) { + DEV_ASSERT(p_state != STATE_UNLOCKED); + if (p_state == STATE_READ) { + if (Locker::thread_state == STATE_UNLOCKED) { + state = STATE_READ; + Locker::thread_state = STATE_READ; + Locker::lock.read_lock(); + } + } else if (p_state == STATE_WRITE) { + if (Locker::thread_state == STATE_UNLOCKED) { + state = STATE_WRITE; + Locker::thread_state = STATE_WRITE; + Locker::lock.write_lock(); + } else if (Locker::thread_state == STATE_READ) { + CRASH_NOW_MSG("Lock can't be upgraded from read to write."); + } + } +} + +ClassDB::Locker::Lock::~Lock() { + if (state == STATE_READ) { + Locker::lock.read_unlock(); + Locker::thread_state = STATE_UNLOCKED; + } else if (state == STATE_WRITE) { + Locker::lock.write_unlock(); + Locker::thread_state = STATE_UNLOCKED; + } +} diff --git a/engine/core/object/class_db.h b/engine/core/object/class_db.h index ed9550cc..f90b691b 100644 --- a/engine/core/object/class_db.h +++ b/engine/core/object/class_db.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef CLASS_DB_H -#define CLASS_DB_H +#pragma once #include "core/object/method_bind.h" #include "core/object/object.h" @@ -79,6 +78,8 @@ MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) { #endif class ClassDB { + friend class Object; + public: enum APIType { API_CORE, @@ -153,7 +154,30 @@ public: return ret; } - static RWLock lock; + // We need a recursive r/w lock because there are various code paths + // that may in turn invoke other entry points with require locking. + class Locker { + public: + enum State { + STATE_UNLOCKED, + STATE_READ, + STATE_WRITE, + }; + + private: + inline static RWLock lock; + inline thread_local static State thread_state = STATE_UNLOCKED; + + public: + class Lock { + State state = STATE_UNLOCKED; + + public: + explicit Lock(State p_state); + ~Lock(); + }; + }; + static HashMap classes; static HashMap resource_base_extensions; static HashMap compat_classes; @@ -171,7 +195,7 @@ public: static APIType current_api; static HashMap api_hashes_cache; - static void _add_class2(const StringName &p_class, const StringName &p_inherits); + static void _add_class(const StringName &p_class, const StringName &p_inherits); static HashMap> default_values; static HashSet default_values_cached; @@ -194,20 +218,14 @@ private: static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector &p_default_args, bool p_compatibility); static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility); - static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true); + static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true, bool p_exposed_only = true); - static bool _can_instantiate(ClassInfo *p_class_info); + static bool _can_instantiate(ClassInfo *p_class_info, bool p_exposed_only = true); public: - // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! - template - static void _add_class() { - _add_class2(T::get_class_static(), T::get_parent_class_static()); - } - template static void register_class(bool p_virtual = false) { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -222,7 +240,7 @@ public: template static void register_abstract_class() { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -235,7 +253,7 @@ public: template static void register_internal_class() { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -250,7 +268,7 @@ public: template static void register_runtime_class() { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -275,7 +293,7 @@ public: template static void register_custom_instance_class() { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); static_assert(std::is_same_v, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); @@ -293,7 +311,7 @@ public: static void get_extension_class_list(const Ref &p_extension, List *p_classes); static ObjectGDExtension *get_placeholder_extension(const StringName &p_class); #endif - static void get_inheriters_from_class(const StringName &p_class, List *p_classes); + static void get_inheriters_from_class(const StringName &p_class, LocalVector &p_classes); static void get_direct_inheriters_from_class(const StringName &p_class, List *p_classes); static StringName get_parent_class_nocheck(const StringName &p_class); static bool get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result); @@ -391,7 +409,7 @@ public: template static MethodBind *bind_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector &p_default_args = Vector(), bool p_return_nil_is_variant = true) { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); ERR_FAIL_NULL_V(bind, nullptr); @@ -404,7 +422,7 @@ public: template static MethodBind *bind_compatibility_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector &p_default_args = Vector(), bool p_return_nil_is_variant = true) { - GLOBAL_LOCK_FUNCTION; + Locker::Lock lock(Locker::STATE_WRITE); MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); ERR_FAIL_NULL_V(bind, nullptr); @@ -498,6 +516,8 @@ public: static void get_native_struct_list(List *r_names); static String get_native_struct_code(const StringName &p_name); static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting + + static Object *_instantiate_allow_unexposed(const StringName &p_class); // Used to create unexposed classes from GDExtension, typically for unexposed EditorPlugin. }; #define BIND_ENUM_CONSTANT(m_constant) \ @@ -563,7 +583,3 @@ _FORCE_INLINE_ Vector errarray(P... p_args) { } #define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class)) - -#include "core/disabled_classes.gen.h" - -#endif // CLASS_DB_H diff --git a/engine/core/object/make_virtuals.py b/engine/core/object/make_virtuals.py index 13775ecd..e130edbc 100644 --- a/engine/core/object/make_virtuals.py +++ b/engine/core/object/make_virtuals.py @@ -15,57 +15,65 @@ script_has_method = """ScriptInstance *_script_instance = ((Object *)(this))->ge }""" proto = """#define GDVIRTUAL$VER($ALIAS $RET m_name $ARG)\\ - StringName _gdvirtual_##$VARNAME##_sn = #m_name;\\ - mutable bool _gdvirtual_##$VARNAME##_initialized = false;\\ mutable void *_gdvirtual_##$VARNAME = nullptr;\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_call($CALLARGS) $CONST {\\ + static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\ $SCRIPTCALL\\ - if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ - MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ - uint32_t hash = mi.get_compatibility_hash();\\ - _gdvirtual_##$VARNAME = nullptr;\\ - if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ - _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - } else if (_get_extension()->get_virtual2) {\\ - _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + if (_get_extension()) {\\ + if (unlikely(!_gdvirtual_##$VARNAME)) {\\ + MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ + uint32_t hash = mi.get_compatibility_hash();\\ + _gdvirtual_##$VARNAME = nullptr;\\ + if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ + _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + } else if (_get_extension()->get_virtual2) {\\ + _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + }\\ + _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ + _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\ + if (_gdvirtual_##$VARNAME == nullptr) {\\ + _gdvirtual_##$VARNAME = reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR);\\ + }\\ }\\ - _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ - _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\ - _gdvirtual_##$VARNAME##_initialized = true;\\ - }\\ - if (_gdvirtual_##$VARNAME) {\\ - $CALLPTRARGS\\ - $CALLPTRRETDEF\\ - if (_get_extension()->call_virtual_with_data) {\\ - _get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\ - $CALLPTRRET\\ - } else {\\ - ((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\ - $CALLPTRRET\\ + if (_gdvirtual_##$VARNAME != reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\ + $CALLPTRARGS\\ + $CALLPTRRETDEF\\ + if (_get_extension()->call_virtual_with_data) {\\ + _get_extension()->call_virtual_with_data(_get_extension_instance(), &_gdvirtual_##$VARNAME##_sn, _gdvirtual_##$VARNAME, $CALLPTRARGPASS, $CALLPTRRETPASS);\\ + $CALLPTRRET\\ + } else {\\ + ((GDExtensionClassCallVirtual)_gdvirtual_##$VARNAME)(_get_extension_instance(), $CALLPTRARGPASS, $CALLPTRRETPASS);\\ + $CALLPTRRET\\ + }\\ + return true;\\ }\\ - return true;\\ }\\ $REQCHECK\\ $RVOID\\ return false;\\ }\\ _FORCE_INLINE_ bool _gdvirtual_##$VARNAME##_overridden() const {\\ + static const StringName _gdvirtual_##$VARNAME##_sn = _scs_create(#m_name, true);\\ $SCRIPTHASMETHOD\\ - if (unlikely(_get_extension() && !_gdvirtual_##$VARNAME##_initialized)) {\\ - MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ - uint32_t hash = mi.get_compatibility_hash();\\ - _gdvirtual_##$VARNAME = nullptr;\\ - if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ - _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ - } else if (_get_extension()->get_virtual2) {\\ - _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + if (_get_extension()) {\\ + if (unlikely(!_gdvirtual_##$VARNAME)) {\\ + MethodInfo mi = _gdvirtual_##$VARNAME##_get_method_info();\\ + uint32_t hash = mi.get_compatibility_hash();\\ + _gdvirtual_##$VARNAME = nullptr;\\ + if (_get_extension()->get_virtual_call_data2 && _get_extension()->call_virtual_with_data) {\\ + _gdvirtual_##$VARNAME = _get_extension()->get_virtual_call_data2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + } else if (_get_extension()->get_virtual2) {\\ + _gdvirtual_##$VARNAME = (void *)_get_extension()->get_virtual2(_get_extension()->class_userdata, &_gdvirtual_##$VARNAME##_sn, hash);\\ + }\\ + _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ + _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME);\\ + if (_gdvirtual_##$VARNAME == nullptr) {\\ + _gdvirtual_##$VARNAME = reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR);\\ + }\\ + }\\ + if (_gdvirtual_##$VARNAME != reinterpret_cast(_INVALID_GDVIRTUAL_FUNC_ADDR)) {\\ + return true;\\ }\\ - _GDVIRTUAL_GET_DEPRECATED(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_sn, $COMPAT)\\ - _GDVIRTUAL_TRACK(_gdvirtual_##$VARNAME, _gdvirtual_##$VARNAME##_initialized);\\ - _gdvirtual_##$VARNAME##_initialized = true;\\ - }\\ - if (_gdvirtual_##$VARNAME) {\\ - return true;\\ }\\ return false;\\ }\\ @@ -207,24 +215,22 @@ def run(target, source, env): max_versions = 12 txt = """/* THIS FILE IS GENERATED DO NOT EDIT */ -#ifndef GDVIRTUAL_GEN_H -#define GDVIRTUAL_GEN_H +#pragma once #include "core/object/script_instance.h" -#include +inline constexpr uintptr_t _INVALID_GDVIRTUAL_FUNC_ADDR = static_cast(-1); #ifdef TOOLS_ENABLED -#define _GDVIRTUAL_TRACK(m_virtual, m_initialized)\\ +#define _GDVIRTUAL_TRACK(m_virtual)\\ if (_get_extension()->reloadable) {\\ VirtualMethodTracker *tracker = memnew(VirtualMethodTracker);\\ tracker->method = (void **)&m_virtual;\\ - tracker->initialized = &m_initialized;\\ tracker->next = virtual_method_list;\\ virtual_method_list = tracker;\\ } #else -#define _GDVIRTUAL_TRACK(m_virtual, m_initialized) +#define _GDVIRTUAL_TRACK(m_virtual) #endif #ifndef DISABLE_DEPRECATED @@ -257,7 +263,5 @@ def run(target, source, env): txt += generate_version(i, True, False, False, True) txt += generate_version(i, True, True, False, True) - txt += "#endif // GDVIRTUAL_GEN_H\n" - with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/engine/core/object/message_queue.cpp b/engine/core/object/message_queue.cpp index 4b0b1ce6..673e60d6 100644 --- a/engine/core/object/message_queue.cpp +++ b/engine/core/object/message_queue.cpp @@ -226,7 +226,7 @@ void CallQueue::_call_function(const Callable &p_callable, const Variant *p_args Error CallQueue::flush() { LOCK_MUTEX; - if (pages.size() == 0) { + if (pages.is_empty()) { // Never allocated UNLOCK_MUTEX; return OK; // Do nothing. @@ -308,7 +308,7 @@ Error CallQueue::flush() { void CallQueue::clear() { LOCK_MUTEX; - if (pages.size() == 0) { + if (pages.is_empty()) { UNLOCK_MUTEX; return; // Nothing to clear. } diff --git a/engine/core/object/message_queue.h b/engine/core/object/message_queue.h index 64e244bd..8a66d0c1 100644 --- a/engine/core/object/message_queue.h +++ b/engine/core/object/message_queue.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef MESSAGE_QUEUE_H -#define MESSAGE_QUEUE_H +#pragma once #include "core/object/object_id.h" #include "core/os/thread_safe.h" @@ -171,5 +170,3 @@ public: MessageQueue(); ~MessageQueue(); }; - -#endif // MESSAGE_QUEUE_H diff --git a/engine/core/object/method_bind.h b/engine/core/object/method_bind.h index a07824a0..93683ee6 100644 --- a/engine/core/object/method_bind.h +++ b/engine/core/object/method_bind.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef METHOD_BIND_H -#define METHOD_BIND_H +#pragma once #include "core/variant/binder_common.h" @@ -143,8 +142,7 @@ public: template class MethodBindVarArgBase : public MethodBind { protected: - R(T::*method) - (const Variant **, int, Callable::CallError &); + R (T::*method)(const Variant **, int, Callable::CallError &); MethodInfo method_info; public: @@ -152,7 +150,7 @@ public: if (p_arg < 0) { return _gen_return_type_info(); } else if (p_arg < method_info.arguments.size()) { - return method_info.arguments.get(p_arg); + return method_info.arguments[p_arg]; } else { return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } @@ -193,11 +191,10 @@ public: Vector names; names.resize(method_info.arguments.size()); #endif - int i = 0; - for (List::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) { - at[i + 1] = itr->type; + for (int64_t i = 0; i < method_info.arguments.size(); ++i) { + at[i + 1] = method_info.arguments[i].type; #ifdef DEBUG_METHODS_ENABLED - names.write[i] = itr->name; + names.write[i] = method_info.arguments[i].name; #endif } @@ -259,11 +256,8 @@ class MethodBindVarArgTR : public MethodBindVarArgBase, friend class MethodBindVarArgBase, T, R, true>; public: -#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) - // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wmaybe-uninitialized") // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { #ifdef TOOLS_ENABLED ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name())); @@ -271,9 +265,7 @@ public: return (static_cast(p_object)->*MethodBindVarArgBase, T, R, true>::method)(p_args, p_arg_count, r_error); } -#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif + GODOT_GCC_WARNING_POP MethodBindVarArgTR( R (T::*p_method)(const Variant **, int, Callable::CallError &), @@ -480,8 +472,7 @@ template template #endif class MethodBindTR : public MethodBind { - R(MB_T::*method) - (P...); + R (MB_T::*method)(P...); protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -576,8 +567,7 @@ template template #endif class MethodBindTRC : public MethodBind { - R(MB_T::*method) - (P...) const; + R (MB_T::*method)(P...) const; protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -728,8 +718,7 @@ MethodBind *create_static_method_bind(void (*p_method)(P...)) { template class MethodBindTRS : public MethodBind { - R(*function) - (P...); + R (*function)(P...); protected: virtual Variant::Type _gen_argument_type(int p_arg) const override { @@ -790,5 +779,3 @@ MethodBind *create_static_method_bind(R (*p_method)(P...)) { MethodBind *a = memnew((MethodBindTRS)(p_method)); return a; } - -#endif // METHOD_BIND_H diff --git a/engine/core/object/object.cpp b/engine/core/object/object.cpp index 8df107ec..852d877f 100644 --- a/engine/core/object/object.cpp +++ b/engine/core/object/object.cpp @@ -115,10 +115,19 @@ TypedArray convert_property_list(const List *p_list) { return va; } +TypedArray convert_property_list(const Vector &p_vector) { + TypedArray va; + for (const PropertyInfo &E : p_vector) { + va.push_back(Dictionary(E)); + } + + return va; +} + MethodInfo::operator Dictionary() const { Dictionary d; d["name"] = name; - d["args"] = convert_property_list(&arguments); + d["args"] = convert_property_list(arguments); Array da; for (int i = 0; i < default_arguments.size(); i++) { da.push_back(default_arguments[i]); @@ -240,21 +249,15 @@ void Object::cancel_free() { } void Object::_initialize() { - _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after _initialize. + // Cache the class name in the object for quick reference. + _class_name_ptr = _get_class_namev(); _initialize_classv(); - _class_name_ptr = nullptr; // May have been called from a constructor. } void Object::_postinitialize() { notification(NOTIFICATION_POSTINITIALIZE); } -void Object::get_valid_parents_static(List *p_parents) { -} - -void Object::_get_valid_parents_static(List *p_parents) { -} - void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid) { #ifdef TOOLS_ENABLED @@ -902,18 +905,14 @@ Variant Object::call_const(const StringName &p_method, const Variant **p_args, i return ret; } -void Object::notification(int p_notification, bool p_reversed) { - if (p_reversed) { - if (script_instance) { - script_instance->notification(p_notification, p_reversed); - } - } else { - _notificationv(p_notification, p_reversed); - } +void Object::_notification_forward(int p_notification) { + // Notify classes starting with Object and ending with most derived subclass. + // e.g. Object -> Node -> Node3D + _notification_forwardv(p_notification); if (_extension) { if (_extension->notification2) { - _extension->notification2(_extension_instance, p_notification, static_cast(p_reversed)); + _extension->notification2(_extension_instance, p_notification, static_cast(false)); #ifndef DISABLE_DEPRECATED } else if (_extension->notification) { _extension->notification(_extension_instance, p_notification); @@ -921,13 +920,29 @@ void Object::notification(int p_notification, bool p_reversed) { } } - if (p_reversed) { - _notificationv(p_notification, p_reversed); - } else { - if (script_instance) { - script_instance->notification(p_notification, p_reversed); + if (script_instance) { + script_instance->notification(p_notification, false); + } +} + +void Object::_notification_backward(int p_notification) { + if (script_instance) { + script_instance->notification(p_notification, true); + } + + if (_extension) { + if (_extension->notification2) { + _extension->notification2(_extension_instance, p_notification, static_cast(true)); +#ifndef DISABLE_DEPRECATED + } else if (_extension->notification) { + _extension->notification(_extension_instance, p_notification); +#endif // DISABLE_DEPRECATED } } + + // Notify classes starting with most derived subclass and ending in Object. + // e.g. Node3D -> Node -> Object + _notification_backwardv(p_notification); } String Object::to_string() { @@ -1080,8 +1095,8 @@ TypedArray Object::_get_method_list_bind() const { get_method_list(&ml); TypedArray ret; - for (List::Element *E = ml.front(); E; E = E->next()) { - Dictionary d = E->get(); + for (const MethodInfo &mi : ml) { + Dictionary d = mi; //va.push_back(d); ret.push_back(d); } @@ -1575,7 +1590,7 @@ void Object::initialize_class() { if (initialized) { return; } - ClassDB::_add_class(); + _add_class_to_classdb(get_class_static(), StringName()); _bind_methods(); _bind_compatibility_methods(); initialized = true; @@ -1640,12 +1655,10 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } break; case Variant::DICTIONARY: { Dictionary d = p_var; - List keys; - d.get_key_list(&keys); - for (const Variant &E : keys) { - _clear_internal_resource_paths(E); - _clear_internal_resource_paths(d[E]); + for (const KeyValue &kv : d) { + _clear_internal_resource_paths(kv.key); + _clear_internal_resource_paths(kv.value); } } break; default: { @@ -1653,9 +1666,20 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } } +void Object::_add_class_to_classdb(const StringName &p_class, const StringName &p_inherits) { + ClassDB::_add_class(p_class, p_inherits); +} + +void Object::_get_property_list_from_classdb(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator) { + ClassDB::get_property_list(p_class, p_list, p_no_inheritance, p_validator); +} + #ifdef TOOLS_ENABLED -void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded) { - set_edited(true); +void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded, bool p_initializing) { + if (!p_initializing) { + set_edited(true); + } + if (p_unfolded) { editor_section_folding.insert(p_section); } else { @@ -1878,7 +1902,7 @@ Variant::Type Object::get_static_property_type(const StringName &p_property, boo } Variant::Type Object::get_static_property_type_indexed(const Vector &p_path, bool *r_valid) const { - if (p_path.size() == 0) { + if (p_path.is_empty()) { if (r_valid) { *r_valid = false; } @@ -1945,6 +1969,20 @@ uint32_t Object::get_edited_version() const { } #endif +const StringName &Object::get_class_name() const { + if (_extension) { + // Can't put inside the unlikely as constructor can run it. + return _extension->class_name; + } + + if (unlikely(!_class_name_ptr)) { + // While class is initializing / deinitializing, constructors and destructors + // need access to the proper class at the proper stage. + return *_get_class_namev(); + } + return *_class_name_ptr; +} + StringName Object::get_class_name_for_extension(const GDExtension *p_library) const { #ifdef TOOLS_ENABLED // If this is the library this extension comes from and it's a placeholder, we @@ -2092,7 +2130,6 @@ void Object::clear_internal_extension() { // Clear the virtual methods. while (virtual_method_list) { (*virtual_method_list->method) = nullptr; - (*virtual_method_list->initialized) = false; virtual_method_list = virtual_method_list->next; } } diff --git a/engine/core/object/object.h b/engine/core/object/object.h index 16d8e19e..1607f827 100644 --- a/engine/core/object/object.h +++ b/engine/core/object/object.h @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef OBJECT_H -#define OBJECT_H +#pragma once +#include "core/disabled_classes.gen.h" #include "core/extension/gdextension_interface.h" #include "core/object/message_queue.h" #include "core/object/object_id.h" @@ -47,6 +47,9 @@ template class TypedArray; +template +class Ref; + enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,hide_slider][,radians_as_degrees][,degrees][,exp][,suffix:] range. @@ -129,6 +132,9 @@ enum PropertyUsageFlags { PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE, }; +// Respective values are defined by disabled_classes.gen.h +#define GD_IS_CLASS_ENABLED(m_class) m_class::_class_is_enabled + #define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal) #define ADD_PROPERTY(m_property, m_setter, m_getter) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter)) #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) @@ -209,6 +215,7 @@ struct PropertyInfo { }; TypedArray convert_property_list(const List *p_list); +TypedArray convert_property_list(const Vector &p_vector); enum MethodFlags { METHOD_FLAG_NORMAL = 1, @@ -227,7 +234,7 @@ struct MethodInfo { PropertyInfo return_val; uint32_t flags = METHOD_FLAGS_DEFAULT; int id = 0; - List arguments; + Vector arguments; Vector default_arguments; int return_val_metadata = 0; Vector arguments_metadata; @@ -256,8 +263,8 @@ struct MethodInfo { return_val(PropertyInfo(pinfo.return_value)), flags(pinfo.flags), id(pinfo.id) { - for (uint32_t j = 0; j < pinfo.argument_count; j++) { - arguments.push_back(PropertyInfo(pinfo.arguments[j])); + for (uint32_t i = 0; i < pinfo.argument_count; i++) { + arguments.push_back(PropertyInfo(pinfo.arguments[i])); } const Variant *def_values = (const Variant *)pinfo.default_arguments; for (uint32_t j = 0; j < pinfo.default_argument_count; j++) { @@ -265,22 +272,12 @@ struct MethodInfo { } } - void _push_params(const PropertyInfo &p_param) { - arguments.push_back(p_param); - } - - template - void _push_params(const PropertyInfo &p_param, VarArgs... p_params) { - arguments.push_back(p_param); - _push_params(p_params...); - } - MethodInfo(const String &p_name) { name = p_name; } template MethodInfo(const String &p_name, VarArgs... p_params) { name = p_name; - _push_params(p_params...); + arguments = Vector{ p_params... }; } MethodInfo(Variant::Type ret) { return_val.type = ret; } @@ -293,7 +290,7 @@ struct MethodInfo { MethodInfo(Variant::Type ret, const String &p_name, VarArgs... p_params) { name = p_name; return_val.type = ret; - _push_params(p_params...); + arguments = Vector{ p_params... }; } MethodInfo(const PropertyInfo &p_ret, const String &p_name) { @@ -305,7 +302,7 @@ struct MethodInfo { MethodInfo(const PropertyInfo &p_ret, const String &p_name, VarArgs... p_params) { return_val = p_ret; name = p_name; - _push_params(p_params...); + arguments = Vector{ p_params... }; } }; @@ -396,57 +393,46 @@ struct ObjectGDExtension { * much alone defines the object model. */ +// This is a barebones version of GDCLASS, +// only intended for simple classes deriving from Object +// so that they can support the `Object::cast_to()` method. +#define GDSOFTCLASS(m_class, m_inherits) \ +public: \ + using self_type = m_class; \ + using super_type = m_inherits; \ + static _FORCE_INLINE_ void *get_class_ptr_static() { \ + static int ptr; \ + return &ptr; \ + } \ + virtual bool is_class_ptr(void *p_ptr) const override { \ + return (p_ptr == get_class_ptr_static()) || m_inherits::is_class_ptr(p_ptr); \ + } \ + \ +private: + #define GDCLASS(m_class, m_inherits) \ + GDSOFTCLASS(m_class, m_inherits) \ private: \ void operator=(const m_class &p_rval) {} \ friend class ::ClassDB; \ \ public: \ - typedef m_class self_type; \ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ - 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 { \ + return &get_class_static(); \ + } \ + static const StringName &get_class_static() { \ static StringName _class_name_static; \ if (unlikely(!_class_name_static)) { \ StringName::assign_static_unique_class_name(&_class_name_static, #m_class); \ } \ - return &_class_name_static; \ - } \ - static _FORCE_INLINE_ void *get_class_ptr_static() { \ - static int ptr; \ - return &ptr; \ - } \ - static _FORCE_INLINE_ String get_class_static() { \ - return String(#m_class); \ - } \ - static _FORCE_INLINE_ String get_parent_class_static() { \ - return m_inherits::get_class_static(); \ - } \ - static void get_inheritance_list_static(List *p_inheritance_list) { \ - m_inherits::get_inheritance_list_static(p_inheritance_list); \ - p_inheritance_list->push_back(String(#m_class)); \ + return _class_name_static; \ } \ 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 *p_parents) { \ - if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \ - m_class::_get_valid_parents_static(p_parents); \ - } \ - \ - m_inherits::get_valid_parents_static(p_parents); \ } \ \ protected: \ @@ -464,7 +450,7 @@ public: return; \ } \ m_inherits::initialize_class(); \ - ::ClassDB::_add_class(); \ + _add_class_to_classdb(get_class_static(), super_type::get_class_static()); \ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ _bind_methods(); \ } \ @@ -479,7 +465,7 @@ protected: initialize_class(); \ } \ _FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &) const { \ - return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_get; \ + return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_get; \ } \ virtual bool _getv(const StringName &p_name, Variant &r_ret) const override { \ if (m_class::_get_get() != m_inherits::_get_get()) { \ @@ -490,7 +476,7 @@ protected: return m_inherits::_getv(p_name, r_ret); \ } \ _FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { \ - return (bool(Object::*)(const StringName &, const Variant &)) & m_class::_set; \ + return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \ } \ virtual bool _setv(const StringName &p_name, const Variant &p_property) override { \ if (m_inherits::_setv(p_name, p_property)) { \ @@ -502,14 +488,14 @@ protected: return false; \ } \ _FORCE_INLINE_ void (Object::*_get_get_property_list() const)(List * p_list) const { \ - return (void(Object::*)(List *) const) & m_class::_get_property_list; \ + return (void (Object::*)(List *) const) & m_class::_get_property_list; \ } \ virtual void _get_property_listv(List *p_list, bool p_reversed) const override { \ if (!p_reversed) { \ m_inherits::_get_property_listv(p_list, p_reversed); \ } \ p_list->push_back(PropertyInfo(Variant::NIL, get_class_static(), PROPERTY_HINT_NONE, get_class_static(), PROPERTY_USAGE_CATEGORY)); \ - ::ClassDB::get_property_list(#m_class, p_list, true, this); \ + _get_property_list_from_classdb(#m_class, p_list, true, this); \ if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \ _get_property_list(p_list); \ } \ @@ -518,7 +504,7 @@ protected: } \ } \ _FORCE_INLINE_ void (Object::*_get_validate_property() const)(PropertyInfo & p_property) const { \ - return (void(Object::*)(PropertyInfo &) const) & m_class::_validate_property; \ + return (void (Object::*)(PropertyInfo &) const) & m_class::_validate_property; \ } \ virtual void _validate_propertyv(PropertyInfo &p_property) const override { \ m_inherits::_validate_propertyv(p_property); \ @@ -527,7 +513,7 @@ protected: } \ } \ _FORCE_INLINE_ bool (Object::*_get_property_can_revert() const)(const StringName &p_name) const { \ - return (bool(Object::*)(const StringName &) const) & m_class::_property_can_revert; \ + return (bool (Object::*)(const StringName &) const) & m_class::_property_can_revert; \ } \ virtual bool _property_can_revertv(const StringName &p_name) const override { \ if (m_class::_get_property_can_revert() != m_inherits::_get_property_can_revert()) { \ @@ -538,7 +524,7 @@ protected: return m_inherits::_property_can_revertv(p_name); \ } \ _FORCE_INLINE_ bool (Object::*_get_property_get_revert() const)(const StringName &p_name, Variant &) const { \ - return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_property_get_revert; \ + return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_property_get_revert; \ } \ virtual bool _property_get_revertv(const StringName &p_name, Variant &r_ret) const override { \ if (m_class::_get_property_get_revert() != m_inherits::_get_property_get_revert()) { \ @@ -549,18 +535,19 @@ protected: return m_inherits::_property_get_revertv(p_name, r_ret); \ } \ _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \ - return (void(Object::*)(int)) & m_class::_notification; \ + return (void (Object::*)(int)) & m_class::_notification; \ } \ - virtual void _notificationv(int p_notification, bool p_reversed) override { \ - if (!p_reversed) { \ - m_inherits::_notificationv(p_notification, p_reversed); \ - } \ + virtual void _notification_forwardv(int p_notification) override { \ + m_inherits::_notification_forwardv(p_notification); \ if (m_class::_get_notification() != m_inherits::_get_notification()) { \ _notification(p_notification); \ } \ - if (p_reversed) { \ - m_inherits::_notificationv(p_notification, p_reversed); \ + } \ + virtual void _notification_backwardv(int p_notification) override { \ + if (m_class::_get_notification() != m_inherits::_get_notification()) { \ + _notification(p_notification); \ } \ + m_inherits::_notification_backwardv(p_notification); \ } \ \ private: @@ -704,7 +691,11 @@ protected: virtual void _validate_propertyv(PropertyInfo &p_property) const {} virtual bool _property_can_revertv(const StringName &p_name) const { return false; } virtual bool _property_get_revertv(const StringName &p_name, Variant &r_property) const { return false; } - virtual void _notificationv(int p_notification, bool p_reversed) {} + + void _notification_forward(int p_notification); + void _notification_backward(int p_notification); + virtual void _notification_forwardv(int p_notification) {} + virtual void _notification_backwardv(int p_notification) {} static void _bind_methods(); static void _bind_compatibility_methods() {} @@ -743,18 +734,12 @@ protected: _FORCE_INLINE_ void (Object::*_get_notification() const)(int) { return &Object::_notification; } - static void get_valid_parents_static(List *p_parents); - static void _get_valid_parents_static(List *p_parents); Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual const StringName *_get_class_namev() const { - static StringName _class_name_static; - if (unlikely(!_class_name_static)) { - StringName::assign_static_unique_class_name(&_class_name_static, "Object"); - } - return &_class_name_static; + return &get_class_static(); } TypedArray _get_meta_list_bind() const; @@ -766,12 +751,14 @@ protected: friend class ClassDB; friend class PlaceholderExtensionInstance; + static void _add_class_to_classdb(const StringName &p_class, const StringName &p_inherits); + static void _get_property_list_from_classdb(const StringName &p_class, List *p_list, bool p_no_inheritance, const Object *p_validator); + bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false); #ifdef TOOLS_ENABLED struct VirtualMethodTracker { void **method; - bool *initialized; VirtualMethodTracker *next; }; @@ -797,12 +784,18 @@ public: template static T *cast_to(Object *p_object) { - return p_object ? dynamic_cast(p_object) : nullptr; + // This is like dynamic_cast, but faster. + // The reason is that we can assume no virtual and multiple inheritance. + static_assert(std::is_base_of_v, "T must be derived from Object"); + static_assert(std::is_same_v, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS"); + return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast(p_object) : nullptr; } template static const T *cast_to(const Object *p_object) { - return p_object ? dynamic_cast(p_object) : nullptr; + static_assert(std::is_base_of_v, "T must be derived from Object"); + static_assert(std::is_same_v, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS"); + return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast(p_object) : nullptr; } enum { @@ -814,17 +807,16 @@ public: }; /* TYPE API */ - static void get_inheritance_list_static(List *p_inheritance_list) { p_inheritance_list->push_back("Object"); } - - static String get_class_static() { return "Object"; } - static String get_parent_class_static() { return String(); } - - virtual String get_class() const { - if (_extension) { - return _extension->class_name.operator String(); + static const StringName &get_class_static() { + static StringName _class_name_static; + if (unlikely(!_class_name_static)) { + StringName::assign_static_unique_class_name(&_class_name_static, "Object"); } - return "Object"; + return _class_name_static; } + + _FORCE_INLINE_ String get_class() const { return get_class_name(); } + virtual String get_save_class() const { return get_class(); } //class stored when saving virtual bool is_class(const String &p_class) const { @@ -835,19 +827,7 @@ public: } 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) { - // Can't put inside the unlikely as constructor can run it - return _extension->class_name; - } - - if (unlikely(!_class_name_ptr)) { - // While class is initializing / deinitializing, constructors and destructurs - // need access to the proper class at the proper stage. - return *_get_class_namev(); - } - return *_class_name_ptr; - } + const StringName &get_class_name() const; StringName get_class_name_for_extension(const GDExtension *p_library) const; @@ -882,7 +862,17 @@ public: return (cerr.error == Callable::CallError::CALL_OK) ? ret : Variant(); } - void notification(int p_notification, bool p_reversed = false); + // Depending on the boolean, we call either the virtual function _notification_backward or _notification_forward. + // - Forward calls subclasses in descending order (e.g. Object -> Node -> Node3D -> extension -> script). + // Backward calls subclasses in descending order (e.g. script -> extension -> Node3D -> Node -> Object). + _FORCE_INLINE_ void notification(int p_notification, bool p_reversed = false) { + if (p_reversed) { + _notification_backward(p_notification); + } else { + _notification_forward(p_notification); + } + } + virtual String to_string(); // Used mainly by script, get and set all INCLUDING string. @@ -974,7 +964,7 @@ public: #ifdef TOOLS_ENABLED virtual void get_argument_options(const StringName &p_function, int p_idx, List *r_options) const; - void editor_set_section_unfold(const String &p_section, bool p_unfolded); + void editor_set_section_unfold(const String &p_section, bool p_unfolded, bool p_initializing = false); bool editor_is_section_unfolded(const String &p_section); const HashSet &editor_get_section_folding() const { return editor_section_folding; } void editor_clear_section_folding() { editor_section_folding.clear(); } @@ -1062,8 +1052,15 @@ public: return object; } + + template + _ALWAYS_INLINE_ static T *get_instance(ObjectID p_instance_id) { + return Object::cast_to(get_instance(p_instance_id)); + } + + template + _ALWAYS_INLINE_ static Ref get_ref(ObjectID p_instance_id); // Defined in ref_counted.h + static void debug_objects(DebugFunc p_func); static int get_object_count(); }; - -#endif // OBJECT_H diff --git a/engine/core/object/object_id.h b/engine/core/object/object_id.h index b04e2df1..2fc66beb 100644 --- a/engine/core/object/object_id.h +++ b/engine/core/object/object_id.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef OBJECT_ID_H -#define OBJECT_ID_H +#pragma once #include "core/typedefs.h" @@ -60,4 +59,5 @@ public: _ALWAYS_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; } }; -#endif // OBJECT_ID_H +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/engine/core/object/ref_counted.h b/engine/core/object/ref_counted.h index 927e457d..3bd2b062 100644 --- a/engine/core/object/ref_counted.h +++ b/engine/core/object/ref_counted.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef REF_COUNTED_H -#define REF_COUNTED_H +#pragma once #include "core/object/class_db.h" #include "core/templates/safe_refcount.h" @@ -86,6 +85,10 @@ class Ref { //virtual RefCounted * get_reference() const { return reference; } public: + static _FORCE_INLINE_ String get_class_static() { + return T::get_class_static(); + } + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { return reference == p_ptr; } @@ -128,6 +131,15 @@ public: ref(p_from); } + void operator=(Ref &&p_from) { + if (reference == p_from.reference) { + return; + } + unref(); + reference = p_from.reference; + p_from.reference = nullptr; + } + template void operator=(const Ref &p_from) { ref_pointer(Object::cast_to(p_from.ptr())); @@ -160,6 +172,11 @@ public: this->operator=(p_from); } + Ref(Ref &&p_from) { + reference = p_from.reference; + p_from.reference = nullptr; + } + template Ref(const Ref &p_from) { this->operator=(p_from); @@ -181,10 +198,15 @@ public: // do a lot of referencing on references and stuff // mutexes will avoid more crashes? - if (reference && reference->unreference()) { - memdelete(reference); + if (reference) { + // NOTE: `reinterpret_cast` is "safe" here because we know `T` has simple linear + // inheritance to `RefCounted`. This guarantees that `T * == `RefCounted *`, which + // allows us to declare `Ref` with forward declared `T` types. + if (reinterpret_cast(reference)->unreference()) { + memdelete(reinterpret_cast(reference)); + } + reference = nullptr; } - reference = nullptr; } template @@ -233,19 +255,6 @@ struct PtrToArg> { } }; -template -struct PtrToArg &> { - typedef Ref EncodeT; - - _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - if (p_ptr == nullptr) { - return Ref(); - } - // p_ptr points to a RefCounted object - return Ref(*((T *const *)p_ptr)); - } -}; - template struct GetTypeInfo> { static const Variant::Type VARIANT_TYPE = Variant::OBJECT; @@ -256,26 +265,17 @@ struct GetTypeInfo> { } }; -template -struct GetTypeInfo &> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); - } -}; - template struct VariantInternalAccessor> { static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } }; +// Zero-constructing Ref initializes reference to nullptr (and thus empty). template -struct VariantInternalAccessor &> { - static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } - static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } -}; +struct is_zero_constructible> : std::true_type {}; -#endif // REF_COUNTED_H +template +Ref ObjectDB::get_ref(ObjectID p_instance_id) { + return Ref(get_instance(p_instance_id)); +} diff --git a/engine/core/object/script_instance.h b/engine/core/object/script_instance.h index 2c8132ec..59b7199c 100644 --- a/engine/core/object/script_instance.h +++ b/engine/core/object/script_instance.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef SCRIPT_INSTANCE_H -#define SCRIPT_INSTANCE_H +#pragma once #include "core/object/ref_counted.h" @@ -96,5 +95,3 @@ public: virtual ScriptLanguage *get_language() = 0; virtual ~ScriptInstance(); }; - -#endif // SCRIPT_INSTANCE_H diff --git a/engine/core/object/script_language.cpp b/engine/core/object/script_language.cpp index 33bf7ab4..a2c738b6 100644 --- a/engine/core/object/script_language.cpp +++ b/engine/core/object/script_language.cpp @@ -633,6 +633,7 @@ void ScriptLanguage::_bind_methods() { BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_PASCAL_CASE); BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_SNAKE_CASE); BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_KEBAB_CASE); + BIND_ENUM_CONSTANT(SCRIPT_NAME_CASING_CAMEL_CASE); } bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) { diff --git a/engine/core/object/script_language.h b/engine/core/object/script_language.h index 8158d633..c724177f 100644 --- a/engine/core/object/script_language.h +++ b/engine/core/object/script_language.h @@ -28,8 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef SCRIPT_LANGUAGE_H -#define SCRIPT_LANGUAGE_H +#pragma once #include "core/doc_data.h" #include "core/io/resource.h" @@ -247,6 +246,7 @@ public: SCRIPT_NAME_CASING_PASCAL_CASE, SCRIPT_NAME_CASING_SNAKE_CASE, SCRIPT_NAME_CASING_KEBAB_CASE, + SCRIPT_NAME_CASING_CAMEL_CASE, }; struct ScriptTemplate { @@ -505,5 +505,3 @@ public: PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref + +